Coverage for apps/pricing_ppe/management/commands/seed_rate_products.py: 100%
13 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
1"""Seed a small dev RateProduct catalog so the pricing endpoints return results locally.
3Idempotent: keyed on (investor, name). Safe to re-run.
4"""
6from decimal import Decimal
8from django.core.management.base import BaseCommand
10from apps.pricing_ppe.models import RateProduct
12_ALL_OCC = ["PrimaryResidence", "SecondHome", "Investment"]
14PRODUCTS = [
15 {
16 "investor": "Fannie Mae",
17 "name": "Conventional 30yr Fixed",
18 "mortgage_type": "Conventional",
19 "term_months": 360,
20 "base_rate": Decimal("6.500"),
21 "base_price": Decimal("100.000"),
22 "min_fico": 620,
23 "max_ltv": Decimal("97.00"),
24 "occupancies": _ALL_OCC,
25 },
26 {
27 "investor": "Fannie Mae",
28 "name": "Conventional 30yr Fixed (Premium)",
29 "mortgage_type": "Conventional",
30 "term_months": 360,
31 "base_rate": Decimal("6.875"),
32 "base_price": Decimal("101.500"),
33 "min_fico": 680,
34 "max_ltv": Decimal("95.00"),
35 "occupancies": ["PrimaryResidence", "SecondHome"],
36 },
37 {
38 "investor": "Freddie Mac",
39 "name": "Conventional 15yr Fixed",
40 "mortgage_type": "Conventional",
41 "term_months": 180,
42 "base_rate": Decimal("5.875"),
43 "base_price": Decimal("100.000"),
44 "min_fico": 700,
45 "max_ltv": Decimal("90.00"),
46 "occupancies": ["PrimaryResidence"],
47 },
48 {
49 "investor": "Ginnie Mae",
50 "name": "FHA 30yr Fixed",
51 "mortgage_type": "FHA",
52 "term_months": 360,
53 "base_rate": Decimal("6.250"),
54 "base_price": Decimal("99.500"),
55 "min_fico": 580,
56 "max_ltv": Decimal("96.50"),
57 "occupancies": ["PrimaryResidence"],
58 },
59 {
60 "investor": "NonAgency Capital",
61 "name": "Investor DSCR 30yr",
62 "mortgage_type": "NonQM",
63 "term_months": 360,
64 "base_rate": Decimal("7.500"),
65 "base_price": Decimal("100.000"),
66 "min_fico": 700,
67 "max_ltv": Decimal("80.00"),
68 "occupancies": ["Investment"],
69 },
70]
73class Command(BaseCommand):
74 help = "Seed a small dev RateProduct catalog (idempotent)."
76 def handle(self, *args, **options):
77 created = 0
78 for spec in PRODUCTS:
79 _, was_created = RateProduct.objects.get_or_create(
80 investor=spec["investor"],
81 name=spec["name"],
82 defaults=spec,
83 )
84 created += int(was_created)
85 self.stdout.write(
86 self.style.SUCCESS(
87 f"Rate products: {created} created, {len(PRODUCTS) - created} already present."
88 )
89 )