Coverage for backend/django/Economics/costing/capital/lang_factors.py: 77%
62 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
1from __future__ import annotations
3from dataclasses import dataclass
4from decimal import Decimal
6from Economics.shared.choices import CostBasis, LangFactorDefaultScope
8from Economics.reference_data.models import EconomicsLangFactorDefault
10from Economics.costing.models import EquipmentMapping
11from Economics.settings_profiles.services.settings_profiles import get_settings_profile
14GLOBAL_LANG_FACTOR_DEFAULT = Decimal("3.000000")
17@dataclass(frozen=True)
18class LangFactorResolution:
19 label: str
20 effective_value: Decimal | None
21 active_default_value: Decimal | None
22 source: str
23 is_custom: bool
24 default_key: str
27def resolve_lang_factor(
28 mapping: EquipmentMapping | None,
29 *,
30 defaults: dict[tuple[str, str], EconomicsLangFactorDefault] | None = None,
31) -> LangFactorResolution:
32 """Resolve effective Lang factor using study defaults before per-item overrides."""
33 if mapping is None: 33 ↛ 34line 33 didn't jump to line 34 because the condition on line 33 was never true
34 default = _global_default(defaults)
35 return _resolution_from_default(default, source="global_default")
37 if mapping.cost_curve_id and mapping.cost_curve.cost_basis == CostBasis.INSTALLED:
38 return LangFactorResolution(
39 label="Lang factor",
40 effective_value=None,
41 active_default_value=None,
42 source="installed_cost_curve",
43 is_custom=False,
44 default_key="installed_cost_no_factor",
45 )
47 if mapping.use_study_lang_factor:
48 settings_profile = get_settings_profile(mapping.costable_item.study)
49 if settings_profile is None:
50 value = GLOBAL_LANG_FACTOR_DEFAULT
51 else:
52 value = settings_profile.default_lang_factor
53 return LangFactorResolution(
54 label="Lang factor",
55 effective_value=value,
56 active_default_value=value,
57 source="study_default",
58 is_custom=False,
59 default_key="study_default_lang_factor",
60 )
62 default = _default_for_mapping(mapping, defaults)
63 if mapping.install_factor is None:
64 return _resolution_from_default(default, source=_default_source(default))
66 return LangFactorResolution(
67 label="Lang factor",
68 effective_value=mapping.install_factor,
69 active_default_value=default.value,
70 source="per_item_override" if mapping.install_factor != default.value else _default_source(default),
71 is_custom=mapping.install_factor != default.value,
72 default_key=default.key,
73 )
76def _default_for_mapping(
77 mapping: EquipmentMapping,
78 defaults: dict[tuple[str, str], EconomicsLangFactorDefault] | None = None,
79) -> EconomicsLangFactorDefault:
80 object_type = ""
81 if mapping.costable_item_id and mapping.costable_item.simulation_object_id: 81 ↛ 83line 81 didn't jump to line 83 because the condition on line 81 was always true
82 object_type = mapping.costable_item.simulation_object.objectType
83 if object_type: 83 ↛ 97line 83 didn't jump to line 97 because the condition on line 83 was always true
84 if defaults is not None: 84 ↛ 85line 84 didn't jump to line 85 because the condition on line 84 was never true
85 default = defaults.get((LangFactorDefaultScope.UNIT_OPERATION_TYPE, object_type))
86 return default if default is not None else _global_default(defaults)
87 default = (
88 EconomicsLangFactorDefault.objects.filter(
89 scope=LangFactorDefaultScope.UNIT_OPERATION_TYPE,
90 unit_operation_type=object_type,
91 )
92 .order_by("pk")
93 .first()
94 )
95 if default is not None:
96 return default
97 return _global_default(defaults)
100def _global_default(
101 defaults: dict[tuple[str, str], EconomicsLangFactorDefault] | None = None,
102) -> EconomicsLangFactorDefault:
103 if defaults is not None: 103 ↛ 104line 103 didn't jump to line 104 because the condition on line 103 was never true
104 default = defaults.get((LangFactorDefaultScope.GLOBAL, ""))
105 if default is not None:
106 return default
107 return _fallback_global_default()
108 default = (
109 EconomicsLangFactorDefault.objects.filter(scope=LangFactorDefaultScope.GLOBAL)
110 .order_by("pk")
111 .first()
112 )
113 if default is not None: 113 ↛ 115line 113 didn't jump to line 115 because the condition on line 113 was always true
114 return default
115 return _fallback_global_default()
118def _fallback_global_default() -> EconomicsLangFactorDefault:
119 """Return the built-in fallback when reference defaults are unavailable."""
120 return EconomicsLangFactorDefault(
121 key="global_lang_factor_3x",
122 scope=LangFactorDefaultScope.GLOBAL,
123 value=GLOBAL_LANG_FACTOR_DEFAULT,
124 label="Global Lang factor default",
125 source_label="Ahuora v1 economics default",
126 )
129def _resolution_from_default(default: EconomicsLangFactorDefault, *, source: str) -> LangFactorResolution:
130 return LangFactorResolution(
131 label="Lang factor",
132 effective_value=default.value,
133 active_default_value=default.value,
134 source=source,
135 is_custom=False,
136 default_key=default.key,
137 )
140def _default_source(default: EconomicsLangFactorDefault) -> str:
141 if default.scope == LangFactorDefaultScope.UNIT_OPERATION_TYPE: 141 ↛ 143line 141 didn't jump to line 143 because the condition on line 141 was always true
142 return "unit_operation_type_default"
143 return "global_default"