Pub 225 Compliance
This commit is contained in:
@@ -55,6 +55,8 @@
|
||||
<v-text-field v-model.number="localAsset.investment_use_percent" type="number" label="Investment use %" />
|
||||
<v-switch v-model="localAsset.listed_property" label="Listed property (≤50% business use → ADS straight-line)" color="primary" density="compact" hide-details class="full" />
|
||||
<v-switch v-model="localAsset.passenger_auto" label="Passenger automobile (§280F annual depreciation caps)" color="primary" density="compact" hide-details class="full" />
|
||||
<v-text-field v-model.number="localAsset.soil_water_deductions" type="number" prefix="$" label="Soil & water conservation deductions (§175 — farm §1252)" />
|
||||
<v-text-field v-model.number="localAsset.cost_sharing_excluded" type="number" prefix="$" label="Excluded cost-sharing payments (§126 — farm §1255)" />
|
||||
|
||||
<v-select
|
||||
v-model="localAsset.special_zone"
|
||||
@@ -328,6 +330,14 @@
|
||||
Net book value {{ currency(disposalPreview.net_book_value) }} ·
|
||||
Proceeds {{ currency(disposalPreview.realized) }} →
|
||||
<strong>{{ disposalPreview.gain_loss >= 0 ? 'Gain' : 'Loss' }} of {{ currency(Math.abs(disposalPreview.gain_loss)) }}</strong>
|
||||
<div v-if="disposalPreview.gain_loss > 0" class="text-caption mt-1">
|
||||
Form 4797 §{{ disposalPreview.recapture_section }}:
|
||||
<strong>{{ currency(disposalPreview.ordinary_recapture) }}</strong> ordinary recapture
|
||||
<span v-if="disposalPreview.section_1252_recapture > 0"> · {{ currency(disposalPreview.section_1252_recapture) }} §1252 (soil/water)</span>
|
||||
<span v-if="disposalPreview.section_1255_recapture > 0"> · {{ currency(disposalPreview.section_1255_recapture) }} §1255 (cost-sharing)</span>
|
||||
<span v-if="disposalPreview.section_1231_gain > 0"> · {{ currency(disposalPreview.section_1231_gain) }} §1231 gain</span>
|
||||
<span v-if="disposalPreview.unrecaptured_1250_gain > 0"> · {{ currency(disposalPreview.unrecaptured_1250_gain) }} unrecaptured §1250 (25%)</span>
|
||||
</div>
|
||||
</v-alert>
|
||||
|
||||
<v-divider class="my-4" />
|
||||
|
||||
92
src/components/ShortTaxYearSettings.vue
Normal file
92
src/components/ShortTaxYearSettings.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<v-card class="span-12 panel-pad">
|
||||
<div class="toolbar-row mb-3">
|
||||
<div>
|
||||
<h2 class="section-title">Short tax years</h2>
|
||||
<p class="quiet text-body-2">
|
||||
Define a tax year shorter than 12 months for the <strong>active company</strong>. That year's MACRS depreciation is
|
||||
prorated by months ÷ 12 (simplified method — most accurate for a placed-in-service short year).
|
||||
</p>
|
||||
</div>
|
||||
<v-spacer />
|
||||
<v-btn color="primary" prepend-icon="mdi-plus" @click="openNew">New year</v-btn>
|
||||
</div>
|
||||
|
||||
<DataTable :columns="columns" :rows="years" row-key="tax_year" :page-size="10" has-actions empty-text="No short tax years — all years are full 12-month years.">
|
||||
<template #cell-months="{ row }">{{ row.months }} months ({{ Math.round((row.months / 12) * 100) }}%)</template>
|
||||
<template #actions="{ row }">
|
||||
<v-btn icon="mdi-pencil" size="small" variant="text" @click="openEdit(row)" />
|
||||
<v-btn icon="mdi-delete-outline" size="small" variant="text" color="error" @click="remove(row)" />
|
||||
</template>
|
||||
</DataTable>
|
||||
<v-alert v-if="error" type="error" density="compact" class="mt-3">{{ error }}</v-alert>
|
||||
|
||||
<v-dialog v-model="dialog" max-width="460">
|
||||
<v-card>
|
||||
<v-card-title>{{ form.exists ? `Edit ${form.tax_year}` : 'New short tax year' }}</v-card-title>
|
||||
<v-card-text>
|
||||
<div class="form-grid">
|
||||
<v-text-field v-model.number="form.tax_year" type="number" label="Tax year *" :disabled="form.exists" />
|
||||
<v-text-field v-model.number="form.months" type="number" label="Months in the tax year (1–12)" min="1" max="12" />
|
||||
<v-text-field v-model="form.note" class="full" label="Note (optional)" />
|
||||
</div>
|
||||
<v-alert v-if="dialogError" type="error" density="compact" class="mt-2">{{ dialogError }}</v-alert>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn variant="text" @click="dialog = false">Cancel</v-btn>
|
||||
<v-btn color="primary" prepend-icon="mdi-content-save" :loading="saving" :disabled="!form.tax_year" @click="save">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DataTable from './DataTable.vue';
|
||||
import { apiRequest } from '../services/api';
|
||||
|
||||
// Short-tax-year config (Admin → Application Configuration), company-scoped via the active company. CRUD
|
||||
// against /api/short-tax-years; the engine prorates that year's MACRS depreciation by months ÷ 12.
|
||||
function blankForm() {
|
||||
return { exists: false, tax_year: new Date().getFullYear(), months: 12, note: '' };
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { DataTable },
|
||||
props: { token: { type: String, required: true } },
|
||||
emits: ['updated'],
|
||||
data() {
|
||||
return {
|
||||
years: [], dialog: false, form: blankForm(), saving: false, error: '', dialogError: '',
|
||||
columns: [{ key: 'tax_year', label: 'Tax year' }, { key: 'months', label: 'Length' }, { key: 'note', label: 'Note' }]
|
||||
};
|
||||
},
|
||||
mounted() { this.load(); },
|
||||
methods: {
|
||||
async api(path, options = {}) { return apiRequest(path, this.token, options); },
|
||||
async load() {
|
||||
this.error = '';
|
||||
try { this.years = (await (await this.api('/api/short-tax-years')).json()).years; }
|
||||
catch (error) { this.error = error.message; }
|
||||
},
|
||||
openNew() { this.form = blankForm(); this.dialogError = ''; this.dialog = true; },
|
||||
openEdit(row) { this.form = { exists: true, tax_year: row.tax_year, months: row.months, note: row.note || '' }; this.dialogError = ''; this.dialog = true; },
|
||||
async save() {
|
||||
if (!this.form.tax_year) return;
|
||||
this.saving = true; this.dialogError = '';
|
||||
try {
|
||||
await this.api('/api/short-tax-years', { method: 'POST', body: JSON.stringify(this.form) });
|
||||
this.dialog = false;
|
||||
await this.load();
|
||||
this.$emit('updated');
|
||||
} catch (error) { this.dialogError = error.message; } finally { this.saving = false; }
|
||||
},
|
||||
async remove(row) {
|
||||
if (!window.confirm(`Remove the short tax year ${row.tax_year}?`)) return;
|
||||
try { await this.api(`/api/short-tax-years/${row.tax_year}`, { method: 'DELETE' }); await this.load(); this.$emit('updated'); }
|
||||
catch (error) { this.error = error.message; }
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -298,10 +298,17 @@
|
||||
<p>
|
||||
Each book’s depreciation is computed from the depreciation-critical fields: property type, placed-in-service date,
|
||||
acquisition value, depreciation method, estimated life, salvage value, Section 168 (bonus) allowance %, Section 179, and
|
||||
business-use %. Supported 200% declining-balance methods include <strong>MF200</strong> (MACRS formula),
|
||||
<strong>MT200</strong> (MACRS tables), and <strong>MI200</strong> (MACRS, Indian-reservation) — which ignore salvage and
|
||||
recover the full basis — and <strong>DB200</strong>, <strong>DH200</strong> (half-year), and <strong>DD200</strong> (full-year),
|
||||
which honor salvage (depreciating only down to it). All switch to straight-line when that yields a larger deduction.
|
||||
business-use %. Supported 200% declining-balance methods include <strong>MF200</strong> (MACRS by formula),
|
||||
<strong>MT200</strong> (MACRS by the <strong>literal IRS Pub 946 Appendix-A percentage tables</strong> for half-year
|
||||
3/5/7/10/15/20-year property — mid-quarter falls back to the equivalent formula), and <strong>MI200</strong>
|
||||
(MACRS, Indian-reservation) — which ignore salvage and recover the full basis — and <strong>DB200</strong>,
|
||||
<strong>DH200</strong> (half-year), and <strong>DD200</strong> (full-year), which honor salvage. All switch to
|
||||
straight-line when that yields a larger deduction.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Short tax years.</strong> If a company's tax year is shorter than 12 months (for example, the year it is
|
||||
formed), define it in <strong>Admin → Application Configuration → Short tax years</strong> and that year's MACRS
|
||||
depreciation is prorated by months ÷ 12 (the simplified method).
|
||||
</p>
|
||||
<v-alert type="info" variant="tonal" density="comfortable" class="manual-callout">
|
||||
When you change a depreciation-critical field on an asset that already has depreciation, a prompt asks <strong>when to apply</strong>
|
||||
@@ -346,7 +353,8 @@
|
||||
<ul>
|
||||
<li><strong>Listed property</strong> — when such an asset is used <strong>50% or less</strong> for qualified
|
||||
business (its <em>Business use %</em>), the engine automatically switches it to <strong>ADS straight-line</strong>
|
||||
and disallows §179 and bonus depreciation, exactly as §280F requires. Above 50%, it depreciates normally.</li>
|
||||
(over the <strong>ADS recovery period from the asset's IRS class</strong> when set) and disallows §179 and bonus
|
||||
depreciation, exactly as §280F requires. Above 50%, it depreciates normally.</li>
|
||||
<li><strong>Passenger automobile</strong> — flags the asset for the annual <strong>luxury-auto depreciation caps</strong>.
|
||||
Each year’s depreciation is limited to the §280F cap for the placed-in-service year (the higher first-year figure
|
||||
applies when bonus is claimed), reduced by the business-use %. Any basis not recovered within the recovery period
|
||||
@@ -369,6 +377,52 @@
|
||||
picks it up</strong> as additional available §179.
|
||||
</p>
|
||||
|
||||
<h3>Depreciation recapture (Form 4797) & §280F recapture</h3>
|
||||
<p>
|
||||
When you dispose of an asset at a <strong>gain</strong>, the system characterizes that gain for Form 4797:
|
||||
</p>
|
||||
<ul>
|
||||
<li><strong>§1245</strong> (equipment / personal property) — the gain is <strong>ordinary-income recapture</strong>
|
||||
up to the total depreciation taken (including §179 and bonus); any gain beyond that is a <strong>§1231</strong>
|
||||
(capital) gain.</li>
|
||||
<li><strong>§1250</strong> (real property) — ordinary recapture applies only to <em>additional</em> depreciation
|
||||
(accelerated over straight-line); since modern MACRS real property is straight-line this is usually zero, and the
|
||||
gain up to straight-line depreciation is shown as <strong>unrecaptured §1250 gain</strong> (the 25% bucket).</li>
|
||||
</ul>
|
||||
<p>
|
||||
The breakdown appears on the <strong>disposal preview</strong> (and is stored on the disposal and shown on the
|
||||
Disposals report). A loss is not recaptured. Recapture is computed on the book you dispose against — use a tax book
|
||||
(e.g. FEDERAL) for the tax characterization.
|
||||
</p>
|
||||
<v-alert type="info" variant="tonal" density="comfortable" class="manual-callout">
|
||||
<strong>§280F recapture.</strong> If a listed-property or passenger-automobile asset's qualified business use drops to
|
||||
<strong>50% or less</strong>, the excess of the accelerated depreciation already claimed over what ADS straight-line
|
||||
would have allowed must be recaptured as ordinary income. The asset's detail view can <strong>preview</strong> this
|
||||
recapture for a chosen conversion year (excess of accelerated-over-ADS through the prior year).
|
||||
</v-alert>
|
||||
|
||||
<h3>Farm property (IRS Pub 225)</h3>
|
||||
<p>
|
||||
Agricultural assets are handled through the same depreciation engine, with farm-specific support:
|
||||
</p>
|
||||
<ul>
|
||||
<li><strong>Recovery periods.</strong> The IRS asset-class catalog includes the farm classes — agricultural
|
||||
machinery (7-yr), farm buildings (20-yr), single-purpose agricultural/horticultural structures (10-yr), fences
|
||||
and grain bins (7-yr), land improvements like wells/irrigation/drainage (15-yr), breeding/dairy/draft livestock
|
||||
and horses (3/5/7-yr by type), and orchards & vineyards — so picking the right asset class sets the period.</li>
|
||||
<li><strong>Method.</strong> Farm property generally uses <strong>150% declining balance</strong> (the
|
||||
<code>macrs_gds_150db_*</code> methods); 3/5/7/10-year farm property placed in service after 2017 may use 200% DB,
|
||||
while 15- and 20-year property stays at 150%. ADS straight-line is available (and required when you elect out of
|
||||
the uniform-capitalization rules — choose an ADS method for that book).</li>
|
||||
<li><strong>§179, bonus & conventions</strong> apply to farm property (including single-purpose structures and
|
||||
grain bins), with the half-year and mid-quarter conventions handled automatically.</li>
|
||||
<li><strong>Farm disposition recapture.</strong> Beyond §1245/§1250, disposing of farm property recaptures
|
||||
<strong>§1252</strong> (soil & water conservation deductions, §175) and <strong>§1255</strong> (excluded
|
||||
cost-sharing payments, §126) as ordinary income, by an applicable percentage based on years held. Enter those
|
||||
amounts on the asset's Details tab (Soil & water conservation / Cost-sharing) and the disposal preview and
|
||||
Disposals report show the §1252/§1255 recapture.</li>
|
||||
</ul>
|
||||
|
||||
<h3>The PM (maintenance) book</h3>
|
||||
<p>
|
||||
A dedicated <strong>PM book</strong> tracks actual maintenance <em>spend</em> per asset rather than depreciation. Its ledger
|
||||
@@ -894,7 +948,7 @@
|
||||
<strong>Admin</strong> (admin role) is where the application is configured. It is split into sub-screens in the
|
||||
navigation rail: <strong>Users & Teams</strong>, <strong>Password & Security</strong>,
|
||||
<strong>Activity & Audit Trail</strong>, <strong>Application Configuration</strong> (companies, application
|
||||
settings, asset classes, depreciation zones, Section 179 limits, §280F passenger-auto limits, asset ID templates, asset categories,
|
||||
settings, asset classes, depreciation zones, Section 179 limits, §280F passenger-auto limits, short tax years, asset ID templates, asset categories,
|
||||
asset departments, PM categories, parts categories, maintenance defaults, tax rule sets), and
|
||||
<strong>Integrations</strong> (email, webhook, Microsoft Teams, ServiceNow, Workday). Each is described below.
|
||||
</p>
|
||||
@@ -1216,7 +1270,7 @@ export default {
|
||||
{ id: 'assets', title: 'Assets — creating & managing', icon: 'mdi-archive-search-outline', keywords: 'asset register create edit import export mass edit workbench files notes tasks warranty' },
|
||||
{ id: 'lifecycle', title: 'Asset lifecycle', icon: 'mdi-cash-remove', keywords: 'dispose disposal sale retire gain loss lease amortization impairment adjustment write down' },
|
||||
{ id: 'barcodes', title: 'Barcodes & scanning', icon: 'mdi-barcode-scan', keywords: 'barcode label print scan camera tag' },
|
||||
{ id: 'books', title: 'Books, depreciation & tax', icon: 'mdi-book-open-variant', keywords: 'book gaap federal depreciation general ledger gl method convention 179 bonus reports journal entry entries import export csv excel conflict merge history zone section 179 280f listed property passenger automobile luxury auto caps ads straight line mid-quarter limitation carryover taxable income macrs' },
|
||||
{ id: 'books', title: 'Books, depreciation & tax', icon: 'mdi-book-open-variant', keywords: 'book gaap federal depreciation general ledger gl method convention 179 bonus reports journal entry entries import export csv excel conflict merge history zone section 179 280f listed property passenger automobile luxury auto caps ads straight line mid-quarter limitation carryover taxable income macrs recapture 1245 1250 1231 form 4797 ordinary gain disposal mt200 tables appendix a short tax year proration ads recovery period farm pub 225 agriculture livestock 1252 1255 soil water conservation cost sharing 150 declining balance' },
|
||||
{ id: 'close', title: 'Period close (month & year-end)', icon: 'mdi-calendar-lock', keywords: 'close month end year end period lock reconcile subledger gl roll forward retained earnings depreciation post reopen finalize wip capitalize disposal impairment audit' },
|
||||
{ id: 'taxrules', title: 'Tax rule sets', icon: 'mdi-scale-balance', keywords: 'tax rules jurisdiction method limits activate version' },
|
||||
{ id: 'templates', title: 'Templates', icon: 'mdi-form-select', keywords: 'template defaults custom fields data entry' },
|
||||
|
||||
@@ -196,6 +196,8 @@
|
||||
|
||||
<Section280fLimitSettings :token="token" />
|
||||
|
||||
<ShortTaxYearSettings :token="token" />
|
||||
|
||||
<AssetIdTemplateSettings :token="token" />
|
||||
|
||||
<CategorySettings :token="token" @updated="$emit('categories-updated')" />
|
||||
@@ -326,6 +328,7 @@ import DepartmentSettings from '../components/DepartmentSettings.vue';
|
||||
import DepreciationZoneSettings from '../components/DepreciationZoneSettings.vue';
|
||||
import Section179LimitSettings from '../components/Section179LimitSettings.vue';
|
||||
import Section280fLimitSettings from '../components/Section280fLimitSettings.vue';
|
||||
import ShortTaxYearSettings from '../components/ShortTaxYearSettings.vue';
|
||||
import NotificationSettings from '../components/NotificationSettings.vue';
|
||||
import PartCategorySettings from '../components/PartCategorySettings.vue';
|
||||
import PmCategorySettings from '../components/PmCategorySettings.vue';
|
||||
@@ -335,7 +338,7 @@ import TeamsSettings from '../components/TeamsSettings.vue';
|
||||
import WebhookSettings from '../components/WebhookSettings.vue';
|
||||
|
||||
export default {
|
||||
components: { AppLogsSettings, AssetClassSettings, AssetIdTemplateSettings, AuditTrailSettings, CategorySettings, CompanySettings, DataTable, DepartmentSettings, DepreciationZoneSettings, NotificationSettings, PartCategorySettings, PasswordPolicySettings, PmCategorySettings, PmSettings, Section179LimitSettings, Section280fLimitSettings, ServiceNowSettings, TeamsSettings, WebhookSettings },
|
||||
components: { AppLogsSettings, AssetClassSettings, AssetIdTemplateSettings, AuditTrailSettings, CategorySettings, CompanySettings, DataTable, DepartmentSettings, DepreciationZoneSettings, NotificationSettings, PartCategorySettings, PasswordPolicySettings, PmCategorySettings, PmSettings, Section179LimitSettings, Section280fLimitSettings, ShortTaxYearSettings, ServiceNowSettings, TeamsSettings, WebhookSettings },
|
||||
props: {
|
||||
token: { type: String, default: '' },
|
||||
section: { type: String, default: 'admin-users' },
|
||||
|
||||
Reference in New Issue
Block a user