""" Options: Date: 2026-06-23 00:02:26 Version: 8.80 Tip: To override a DTO option, remove "#" prefix before updating BaseUrl: https://api.dev.dynamics.trendsic.com #GlobalNamespace: #AddServiceStackTypes: True #AddResponseStatus: False #AddImplicitVersion: #AddDescriptionAsComments: True IncludeTypes: PmProjectDetailRequest.* #ExcludeTypes: #DefaultImports: datetime,decimal,marshmallow.fields:*,servicestack:*,typing:*,dataclasses:dataclass/field,dataclasses_json:dataclass_json/LetterCase/Undefined/config,enum:Enum/IntEnum #DataClass: #DataClassJson: """ import datetime import decimal from marshmallow.fields import * from servicestack import * from typing import * from dataclasses import dataclass, field from dataclasses_json import dataclass_json, LetterCase, Undefined, config from enum import Enum, IntEnum @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmFinance: budget: float = 0.0 spent: float = 0.0 estimated_cost: float = 0.0 crew_cost: float = 0.0 equip_cost: float = 0.0 mat_cost: float = 0.0 variance: float = 0.0 health_pct: int = 0 spent_pct: int = 0 progress_pct: int = 0 @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmReadiness: jobs_no_crew: int = 0 open_roles: int = 0 equipment_conflicts: int = 0 material_gaps: int = 0 total_gaps: int = 0 ready_pct: int = 0 @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmJobCrew: contact_i_d: int = 0 name: Optional[str] = None rate: float = 0.0 budgeted_hours: float = 0.0 is_open: bool = False @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmJobResource: id: int = 0 name: Optional[str] = None amount: float = 0.0 qty: int = 0 @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmJob: job_i_d: int = 0 name: Optional[str] = None description: Optional[str] = None status: Optional[str] = None start_date: Optional[str] = None end_date: Optional[str] = None crew_count: int = 0 budgeted_hours: float = 0.0 equipment_count: int = 0 material_count: int = 0 crew_cost: float = 0.0 equip_cost: float = 0.0 mat_cost: float = 0.0 cost: float = 0.0 no_crew: bool = False equip_conflict: bool = False material_gap: bool = False ready_pct: int = 0 crew: List[PmJobCrew] = field(default_factory=list) equipment: List[PmJobResource] = field(default_factory=list) materials: List[PmJobResource] = field(default_factory=list) @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmConflict: project_name: Optional[str] = None job_name: Optional[str] = None start_date: Optional[str] = None end_date: Optional[str] = None @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmEquipmentRow: equipment_i_d: int = 0 name: Optional[str] = None equipment_type: Optional[str] = None serial_number: Optional[str] = None used_by_jobs: Optional[str] = None available: bool = False conflicts: List[PmConflict] = field(default_factory=list) maintenance_interval_days: Optional[int] = None last_service_date: Optional[str] = None next_service_date: Optional[str] = None maintenance_state: Optional[str] = None @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmMaterialRow: material_i_d: int = 0 name: Optional[str] = None material_type: Optional[str] = None on_hand: int = 0 needed_by_jobs: int = 0 qty_needed: int = 0 to_order: int = 0 unit_cost: float = 0.0 line_cost: float = 0.0 project_material_i_d: int = 0 status_i_d: int = 0 status: Optional[str] = None supplier: Optional[str] = None order_date: Optional[str] = None delivery_date: Optional[str] = None shortfall: bool = False @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmCalendarBar: job_i_d: int = 0 name: Optional[str] = None start_date: Optional[str] = None end_date: Optional[str] = None status: Optional[str] = None @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmCatalogItem: id: int = 0 name: Optional[str] = None amount: float = 0.0 @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmProjectDetail: project_i_d: int = 0 project_u_i_d: Optional[str] = None name: Optional[str] = None client: Optional[str] = None project_type: Optional[str] = None status: Optional[str] = None branch: Optional[str] = None start_date: Optional[str] = None end_date: Optional[str] = None description: Optional[str] = None finance: Optional[PmFinance] = None readiness: Optional[PmReadiness] = None jobs: List[PmJob] = field(default_factory=list) equipment: List[PmEquipmentRow] = field(default_factory=list) materials: List[PmMaterialRow] = field(default_factory=list) calendar: List[PmCalendarBar] = field(default_factory=list) project_statuses: List[PmCatalogItem] = field(default_factory=list) response_status: Optional[ResponseStatus] = None # @Route("/v1/pm/project/{Uid}", "GET,OPTIONS") @dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE) @dataclass class PmProjectDetailRequest(IReturn[PmProjectDetail]): uid: Optional[str] = None