This commit is contained in:
Chris Chen
2026-06-24 21:37:41 -07:00
parent 9f91683633
commit 46a4298a71
4 changed files with 314 additions and 5 deletions
+46 -5
View File
@@ -38,11 +38,11 @@ public static class DbSeeder
("Food & Beverage", "餐飲", 3, [("Catering","出餐費用"),("Food Ingredients","食材採購"),("Utensils","器具"),("Disposable Tableware","一次性餐具")]),
("Training", "培訓", 4, [("Course Fees","課程費用"),("Books","書籍"),("Conference","研討會"),("Travel","差旅")]),
("Materials", "教材", 5, [("Curriculum Printing","教材印刷"),("Craft Supplies","手工材料"),("Copyright & Licensing","版權購買")]),
("Facility", "場地", 6, [("Rent","場地租金"),("Utilities","水電"),("Property Insurance","財產保險"),("Decoration","裝飾")]),
("Facility", "場地", 6, [("Rent","場地租金"),("Utilities","水電"),("Property Insurance","財產保險"),("Decoration","裝飾"),("Repairs & Maintenance","修繕維護")]),
("Printing", "印刷", 7, [("Bulletins","週報"),("Order of Service","程序單"),("Posters","海報"),("Advertising & Promotion","廣告推廣")]),
("Missions", "宣教", 8, [("Offering Transfer","奉獻轉帳"),("Missionary Support","宣教士支援"),("Foreign Missions Support","國外宣教支援"),("Travel","差旅")]),
("Benevolence", "關懷救助", 9, [("Emergency Aid","急難救助"),("Condolence Gifts","慰問禮品"),("Visit Expenses","探訪費用")]),
("Other", "其他", 10, [("Miscellaneous","雜支")]),
("Other", "其他", 10, [("Miscellaneous","雜支"),("Gifts","禮品")]),
("Personnel", "人事", 11, [("Officer / Key Employee Compensation","主要職員薪酬"),("Salary & Wages","薪資"),("Payroll Taxes","薪資稅費"),("Employee Benefits","員工福利"),("Retirement / Pension","退休金"),("Workers Compensation","勞工保險"),("Honorarium","酬庸"),("Staff Training","同工進修"),("Contract Labor","外包勞務")]),
("Professional Services", "專業服務", 12, [("Legal","法律服務"),("Accounting & Audit","會計與審計"),("Other Professional","其他專業服務")]),
("Information Technology", "資訊科技", 13, [("Software & Subscriptions","軟體與訂閱"),("Website & Hosting","網站與主機"),("Internet & Telecom","網路與電信")]),
@@ -91,23 +91,36 @@ public static class DbSeeder
("Facility", "Utilities", "16"),
("Facility", "Property Insurance", "23"),
("Facility", "Decoration", "24"),
// Building repairs & maintenance (plumbing, electrical, painting) are part of Occupancy.
("Facility", "Repairs & Maintenance", "16"),
("Training", "Course Fees", "19"),
("Training", "Conference", "19"),
("Training", "Books", "24"),
("Training", "Travel", "17"),
("Missions", "Travel", "17"),
("Missions", "Offering Transfer", "1"),
("Missions", "Missionary Support", "1"),
// Domestic missions support is paid to individual missionaries/families → line 2 (grants to individuals).
("Missions", "Offering Transfer", "2"),
("Missions", "Missionary Support", "2"),
("Missions", "Foreign Missions Support", "3"),
("Benevolence", "Emergency Aid", "2"),
("Benevolence", "Condolence Gifts", "2"),
("Benevolence", "Visit Expenses", "2"),
// Visitation is the church's own travel/program cost, not a grant to an individual.
("Benevolence", "Visit Expenses", "17"),
("Consumables", "Office Supplies", "13"),
// General supplies belong with office expenses (line 13), not the "Other" catch-all.
("Consumables", "Batteries", "13"),
("Consumables", "Accessories", "13"),
("Consumables", "Cleaning Supplies", "13"),
// IRS line 13 covers equipment rental and maintenance.
("Equipment", "Rental", "13"),
("Equipment", "Maintenance & Repair", "13"),
("Printing", "Bulletins", "13"),
("Printing", "Order of Service", "13"),
("Printing", "Posters", "12"),
("Printing", "Advertising & Promotion", "12"),
("Materials", "Curriculum Printing", "13"),
// Classroom/craft supplies fall under IRS line 13 office expenses ("supplies… classroom…").
("Materials", "Craft Supplies", "13"),
("Professional Services", "Legal", "11b"),
("Professional Services", "Accounting & Audit", "11c"),
("Professional Services", "Other Professional", "11g"),
@@ -115,6 +128,22 @@ public static class DbSeeder
("Information Technology", "Website & Hosting", "14"),
("Information Technology", "Internet & Telecom", "14"),
("Finance & Banking", "Interest", "20"),
// Bank/processing fees are office expenses per IRS line 13 (consistent with Interest → 20).
("Finance & Banking", "Bank & Processing Fees", "13"),
// Appreciation/outreach gifts have no natural 990 line; mapped to 24 explicitly so this
// deliberate "Other" choice doesn't inflate UnmappedExpenseCount. (Benevolence gifts → line 2.)
("Other", "Gifts", "24"),
];
// One-time corrections for subcategories that were mapped to the WRONG line in an earlier
// seed. The normal mapping loop below only fills NULLs, so it cannot fix an existing bad
// value — this block does. Idempotent: each row fires only while the subcategory still holds
// the OLD line, so it never clobbers a deliberate admin re-mapping. (GroupEn, SubEn, Old, New)
private static readonly (string GroupEn, string SubEn, string OldCode, string NewCode)[] Form990RemapSeed =
[
("Benevolence", "Visit Expenses", "2", "17"),
("Missions", "Missionary Support", "1", "2"),
("Missions", "Offering Transfer", "1", "2"),
];
private static readonly (string Name, string Description)[] Roles =
@@ -329,6 +358,18 @@ public static class DbSeeder
if (sub is not null && sub.Form990LineId is null && linesByCode.TryGetValue(code, out var lineId))
sub.Form990LineId = lineId;
}
// Correct earlier mis-mappings on existing databases (see Form990RemapSeed). Only fires
// while the subcategory still holds the OLD line, so a later admin edit is never clobbered.
foreach (var (groupEn, subEn, oldCode, newCode) in Form990RemapSeed)
{
var sub = subsByKey.FirstOrDefault(s => s.Group!.Name_en == groupEn && s.Name_en == subEn);
if (sub is null) continue;
if (linesByCode.TryGetValue(oldCode, out var oldId)
&& linesByCode.TryGetValue(newCode, out var newId)
&& sub.Form990LineId == oldId)
sub.Form990LineId = newId;
}
await db.SaveChangesAsync();
}