Skip to content

Estate Model Overview

The Estate object represents a real estate property listing in Destinet - whether it's an apartment, house, commercial space, or land for sale. It's designed to accommodate data from multiple real estate management systems (Vitec, etc.) while maintaining a consistent structure.

What Makes Estate Central

Estate is the core entity that:

  • Represents individual properties for sale or rent
  • Can be standalone (existing buildings) or part of a Project (new builds)
  • References Department and Employee entities via IDs (not embedded data)
  • Supports all property types: residential, commercial, industrial, agricultural
  • Stores comprehensive property information from various source systems

Design Principles


1. Source System Flexibility

The Estate model is designed to work with data from multiple source systems:

  • Integer Enums: Property types, ownership types, and statuses are stored as integer enum values directly from the source system (e.g., Vitec)
  • Origin Metadata: Source-specific data that doesn't fit the standard model is stored in CustomData dictionary
  • Origin Tracking: The Origin field identifies which system provided the data ("Vitec", etc.)

Benefit: Preserves exact source data, avoids conversion overhead, and allows system-specific features to be stored without model changes.

2. References Instead of Embedded Data

To avoid data duplication and enable updates to propagate automatically:

  • DepartmentId → References the Department collection (not embedded department data)
  • BrokersIdWithRoles → List of broker/employee references with role assignments
  • ProjectId → For new builds, references the Project collection

Benefit: Update an employee's email once → reflects on all estates automatically.

3. Comprehensive Property Information

The Estate model captures everything needed to market and sell a property:

  • Core Details: Rooms, bathrooms, floor, construction year, etc.
  • Area Measurements (EstateSize): Primary room area, gross area, usable area, etc.
  • Pricing (EstatePrice): Asking price, sold price, costs, fees, collective debt, etc.
  • Ownership Details (PartOwnership): Cooperative/condominium information
  • Location: Full address + geo coordinates + cadastral information (matrikkel)
  • Marketing Content: Headlines, description sections, images, documents, links
  • Energy Rating: Energy letter and color code
  • Showings: Scheduled viewings with notes

4. Multi-Endpoint Data Population

Estate data is populated from multiple API endpoints:

  • Base estate data from main endpoint
  • Images fetched separately and populated into Images list
  • Documents fetched separately and populated into Documents list
  • Links fetched separately and populated into Links list
  • Showings fetched separately and populated into Showings list

Benefit: The Estate object serves as a complete, denormalized representation once populated.

5. Rich Media Support

Properties can showcase themselves through multiple media types:

  • Images (ImageCollection): Facade, interior, floor plans with categorization
  • Documents (DocumentCollection): PDFs, prospectuses, legal documents
  • Links (List<PropertyLink>): Virtual tours, videos, external links
  • Showings (List<Showing>): Open house schedules
  • External Platform URLs (ExternalPlatformUrls): Links to Finn.no, Hemnet, etc.

Core Structure

public class Estate
{
    // ============================================
    // CORE IDENTIFICATION
    // ============================================

    public string? Heading { get; set; }              // Marketing headline
    public string Id { get; set; }                    // Unique estate identifier
    public string? AssignmentNum { get; set; }        // Assignment/reference number
    public int? DepartmentId { get; set; }            // Department ID
    public DateTime? ChangedDate { get; set; }        // Last change timestamp

    // ============================================
    // BROKERS
    // ============================================

    public List<BrokerWithRole>? BrokersIdWithRoles { get; set; }

    // ============================================
    // CLASSIFICATION & TYPE
    // ============================================

    public int? EstateBaseType { get; set; }          // Base property type (enum)
    public int? AssignmentTypeGroup { get; set; }     // Assignment type (enum)
    public int? Ownership { get; set; }               // Ownership type (enum)

    // ============================================
    // STATUS
    // ============================================

    public int Status { get; set; }                   // Current status (enum)
    public DateTime? SoldDate { get; set; }
    public DateTime? ExpireDate { get; set; }

    // ============================================
    // LOCATION
    // ============================================

    public Address? Address { get; set; }
    public GeoCoordinates? GeoCoordinates { get; set; }
    public List<Matrikkel>? Matrikkel { get; set; }   // Cadastral information

    // ============================================
    // PROPERTY DETAILS
    // ============================================

    public int? NoOfRooms { get; set; }
    public int? NoOfBedRooms { get; set; }
    public int? NoOfBathRooms { get; set; }
    public int? Floor { get; set; }
    public int? ConstructionYear { get; set; }
    public Plot? Plot { get; set; }
    public EstateSize? EstateSize { get; set; }

    // ============================================
    // ENERGY
    // ============================================

    public EnergyRating? EnergyRating { get; set; }

    // ============================================
    // PRICING
    // ============================================

    public EstatePrice? EstatePrice { get; set; }

    // ============================================
    // OWNERSHIP
    // ============================================

    public PartOwnership? PartOwnership { get; set; }

    // ============================================
    // FACILITIES & FEATURES
    // ============================================

    public List<string>? EstateFacilities { get; set; }  // Human-readable names
    public List<int>? Facilities { get; set; }           // Enum values

    // ============================================
    // SHOWINGS/VIEWINGS
    // ============================================

    public List<Showing>? Showings { get; set; }
    public string? ShowingNote { get; set; }

    // ============================================
    // MEDIA & LINKS
    // ============================================

    public List<PropertyLink>? Links { get; set; }
    public ImageCollection? Images { get; set; }
    public DocumentCollection? Documents { get; set; }

    // ============================================
    // DESCRIPTION
    // ============================================

    public List<DescriptionSection>? DescriptionSections { get; set; }

    // ============================================
    // PROJECT REFERENCE
    // ============================================

    public string? ProjectId { get; set; }           // For new builds

    // ============================================
    // OTHER
    // ============================================

    public string? Tag { get; set; }                 // Custom tag/identifier

    // ============================================
    // ORIGIN DATA
    // ============================================

    public string? Origin { get; set; }              // Source system name
    public Dictionary<string, object>? CustomData { get; set; }
}

Property Classification Enums

The model uses integer enum values directly from the source system (e.g., Vitec). Enum mapping tables are needed to convert these to human-readable strings.

EstateBaseType (Vitec: estateBaseType)

Base type of property:

  • 0 = NotSet
  • 1 = Detached
  • 2 = Leisure
  • 3 = Business
  • 4 = Project
  • 5 = Plot
  • 6 = Unknown

AssignmentTypeGroup (Vitec: assignmentTypeGroup)

Assignment type group:

  • 0 = NotSet
  • 1 = Sale
  • 2 = Rent
  • 3 = LettingService
  • 4 = ProjectSale
  • etc.

Ownership (Vitec: ownership)

Type of ownership:

  • 0 = Owned
  • 1 = Cooperative
  • 2 = Stock
  • 3 = Bond
  • 4 = Condominium

Status (Vitec: status)

Current listing status:

  • 0 = Request
  • 1 = Preparation
  • 2 = ForSale
  • 3 = Sold
  • 4 = Reserved
  • 5 = Archived
  • 6 = Expired
  • 7 = Terminated

Note: See Vitec Enum Mappings for complete enum value documentation.

Estate-Specific Classes

These classes are specific to the Estate model and defined in the estate folder:

BrokerWithRole

Represents a broker/employee assigned to an estate with a specific role:

public class BrokerWithRole
{
    public string EmployeeId { get; set; }       // Reference to Employee
    public int BrokerRole { get; set; }          // Role enum (primary, secondary, etc.)
}

Plot

Plot/land information:

public class Plot
{
    public bool Owned { get; set; }              // Whether plot is owned vs leased
    public decimal? Size { get; set; }           // Plot area in square meters
    public string Description { get; set; }      // Description of the plot
}

EstateSize

Area measurements for the property:

public class EstateSize
{
    public decimal? PrimaryRoomArea { get; set; }        // P-ROM (Primærrom)
    public decimal? GrossArea { get; set; }              // BRA (Bruksareal) - gross floor area
    public decimal? UsableArea { get; set; }             // Usable area
    // ... and other area measurements
}

EstatePrice

Comprehensive pricing information:

public class EstatePrice
{
    public decimal? PriceSuggestion { get; set; }        // Asking price
    public decimal? SoldPrice { get; set; }              // Final sold price
    public decimal? CollectiveDebt { get; set; }         // Fellesgjeld
    public RentInfo Rent { get; set; }                   // Rent/common costs
    public decimal? PurchaseCostsAmount { get; set; }    // Omkostninger
    public decimal? TotalPrice { get; set; }             // Total price
    // ... and many other price-related fields
}

PartOwnership

Cooperative/condominium ownership details (Norwegian: Borettslag):

public class PartOwnership
{
    public string PartName { get; set; }                 // Cooperative name
    public string PartOrgNumber { get; set; }            // Organization number
    public string PartAbout { get; set; }                // About the cooperative
    public decimal? Deposit { get; set; }                // Innskudd
    public decimal? ShareJointDebtYear { get; set; }     // Andel fellesgjeld
    public string BoardApproval { get; set; }            // Styregodkjenning info
    // ... and many other cooperative-specific fields
}

For detailed documentation of all estate-specific classes with complete property tables and examples, see Estate Classes.

Shared Classes

These classes are shared across Estate, Project, Department, Employee, and other models. Full documentation is available in the Shared Classes section.

Core Shared Classes

Working with Estate Data

Example: Creating a Complete Estate Object

var estate = new Estate
{
    // Core Identification
    Heading = "Lekker 3-roms leilighet i sentrum",
    EstateId = "3221523",
    AssignmentNum = "110250256",
    DepartmentId = 3005093,
    ChangedDate = DateTime.Parse("2025-10-28T14:39:00Z"),

    // Brokers
    BrokersIdWithRoles = new List<BrokerWithRole>
    {
        new BrokerWithRole
        {
            EmployeeId = "3006722",
            BrokerRole = 1  // Primary broker
        }
    },

    // Classification (using Vitec enum values)
    EstateBaseType = 1,           // Detached/Residential
    AssignmentTypeGroup = 1,      // Sale
    Ownership = 1,                // Cooperative

    // Status
    Status = 2,                   // ForSale
    ExpireDate = DateTime.Parse("2026-04-20"),

    // Location
    Address = new Address
    {
        Street = "Storgata 10",
        ZipCode = "0155",
        City = "Oslo",
        Municipality = "Oslo",
        Country = "Norway"
    },

    GeoCoordinates = new GeoCoordinates
    {
        Latitude = 59.9139m,
        Longitude = 10.7522m
    },

    // Property Details
    NoOfRooms = 3,
    NoOfBedRooms = 2,
    NoOfBathRooms = 1,
    Floor = 3,
    ConstructionYear = 1985,

    EstateSize = new EstateSize
    {
        PrimaryRoomArea = 70.0m,
        GrossArea = 95.5m,
        UsableArea = 88.0m
    },

    // Pricing
    EstatePrice = new EstatePrice
    {
        PriceSuggestion = 4500000,
        CollectiveDebt = 250000
    },

    // Origin
    Origin = "Vitec"
};

// Add images from separate endpoint
estate.Images.Add(new Image
{
    Id = "4821283",
    OriginalUrl = "https://cdn.example.com/facade.jpg",
    Category = "Facade",
    Order = 1
});

// Add description sections
estate.DescriptionSections.Add(new DescriptionSection
{
    GroupName = "BELIGGENHET",
    Title = "Beliggenhet",
    Content = "Leiligheten ligger sentralt i Oslo...",
    Order = 1
});

Data Population Flow

When fetching estate data from Vitec (or other systems):

  1. Fetch base estate: GET /{installationId}/Estates/{estateId}
  2. Fetch images: GET /{installationId}/Estates/{estateId}/Images
  3. Fetch documents: GET /{installationId}/Estates/{estateId}/Documents
  4. Fetch links: GET /{installationId}/Estates/{estateId}/Links
  5. Fetch showings: GET /{installationId}/Estates/{estateId}/Showings
  6. Combine all data into single Estate object

The Estate model is designed to hold this complete, denormalized view of the property.

Relationship to Other Models

Estate → Department (Many-to-One)

estate.DepartmentId = 3005093;
var department = GetDepartmentById(estate.DepartmentId);

Estate → Employee (Many-to-Many via BrokerWithRole)

foreach (var broker in estate.BrokersIdWithRoles)
{
    var employee = GetEmployeeById(broker.EmployeeId);
    // employee has role: broker.BrokerRole
}

Estate → Project (Many-to-One, optional)

if (estate.ProjectId != null)
{
    var project = GetProjectById(estate.ProjectId);
    // This is a new build unit within a housing project
}

Next Steps