{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/arcnm-io/json-schema/arcnm-io-environment-economics-update-schema.json",
  "title": "EnvironmentEconomicsUpdate",
  "description": "PATCH body — omit a field to keep it, send ``null`` to clear it.\n\nClearing stores SQL NULL on every field here, including the five\ninspection / holding scalars: since 0157 those columns are nullable\ntoo, so a cleared value inherits from the parent environment again and\nends at the platform default, exactly like the rest. Bounds are sanity\nwindows in the environment's own currency — the write surface is where\nsanity lives (same stance as the effective-rates edit).",
  "x-generated": "2026-11-01",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/arcnm-io-openapi.yml#/components/schemas/EnvironmentEconomicsUpdate",
  "properties": {
    "energy_eur_per_kwh": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 1000.0,
          "exclusiveMinimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Energy Eur Per Kwh",
      "description": "Stated energy price per kWh, in the environment's currency; null clears back to inherit / platform default."
    },
    "space_eur_per_m2_y": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 100000.0,
          "exclusiveMinimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Space Eur Per M2 Y",
      "description": "Stated floor-space cost per m² and year, in the environment's currency; null clears back to inherit / platform default."
    },
    "default_material_family": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 64
        },
        {
          "type": "null"
        }
      ],
      "title": "Default Material Family",
      "description": "Default material family for calculations that name no grade (steel, stainless, aluminum, titanium, nickel, other); null clears back to inherit / platform default."
    },
    "material_overhead_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 10.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Material Overhead Pct",
      "description": "Procurement / storage surcharge on material cost (0.07 = 7 %); null clears back to inherit / platform default. The platform states no variable overhead of its own, so nothing is switched off; a variable overhead you state yourself still applies beside it."
    },
    "production_overhead_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 10.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Production Overhead Pct",
      "description": "Surcharge on production wages (0.80 = 80 %); null clears back to inherit / platform default. The platform states no variable overhead of its own, so nothing is switched off; a variable overhead you state yourself still applies beside it."
    },
    "sga_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 10.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Sga Pct",
      "description": "Administration and selling surcharge on manufacturing cost (0.12 = 12 %); null clears back to inherit / platform default."
    },
    "margin_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 10.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Margin Pct",
      "description": "Profit mark-up on total cost (0.10 = 10 %); null clears back to inherit / platform default, which adds none."
    },
    "freight_eur_per_part": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 100000.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Freight Eur Per Part",
      "description": "Outbound freight per unit, in the environment's currency; null clears back to inherit / platform default."
    },
    "duty_eur_per_part": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 100000.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Duty Eur Per Part",
      "description": "Customs duty per unit, in the environment's currency; null clears back to inherit / platform default."
    },
    "packaging_eur_per_part": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 100000.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Packaging Eur Per Part",
      "description": "Packaging material per unit (Sondereinzelkosten des Vertriebs), in the environment's currency; the packing labour is priced on the labour line, not here. Null clears back to inherit / platform default."
    },
    "cash_discount_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 0.25,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Cash Discount Pct",
      "description": "Customer cash discount (Kundenskonto) priced into the offer 'im Hundert' (0.02 = 2 %): it is a share of the target price that already contains it, so a customer who deducts it still pays the cash price. Null clears back to inherit / platform default, which prices none."
    },
    "sales_commission_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 0.25,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Sales Commission Pct",
      "description": "Sales commission (Vertreterprovision) priced into the offer 'im Hundert', as a share of the target price. Null clears back to inherit / platform default, which prices none."
    },
    "customer_discount_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 0.5,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Customer Discount Pct",
      "description": "Customer discount (Kundenrabatt) priced into the offer 'im Hundert', as a share of the list price (the offer price). Null clears back to inherit / platform default, which prices none."
    },
    "reject_rate_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 0.5,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Reject Rate Pct",
      "description": "Share of the parts this shop STARTS that it rejects, as a fraction (0.03 = 3 %, not 3). It is a yield, not a surcharge: to ship 100 good parts at 0.03 the shop starts 104, and the stock drawn for the four that never shipped is charged to the ones that did. Charged on the base reject_rate_base names: the material draw by default, or the whole part when the shop finds its rejects at final inspection. Must be below 0.5 — half a shop's output failing is a process problem, not a costing input. Null clears back to inherit / platform default, which rejects nothing."
    },
    "reject_rate_base": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "material",
            "herstellkosten"
          ]
        },
        {
          "type": "null"
        }
      ],
      "title": "Reject Rate Base",
      "description": "What a reject costs. 'material' charges the reject rate on the stock drawn for the parts that fail — the lower bound, right when rejects are found at the first operation. 'herstellkosten' charges it on the whole part before scrap (material, manufacturing and their overheads), the industry convention for end-item scrap found at final inspection. One method, never both. Null clears back to inherit / platform default, 'material'."
    },
    "scrap_credit_eur_per_kg": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 100000.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Scrap Credit Eur Per Kg",
      "description": "Scrap credit (Reststoffgutschrift): the flat return per kg of scrap, in the environment's currency — what the dealer pays less what sorting, containers and haulage cost you. Paid on the scrap a dealer buys (sheet skeleton, chips, cut-offs) wherever no scrap price is stated for that kind of scrap; never on a reusable remnant or on the part itself. The credit is never more than the material cost; it reduces the material before the material overhead and a material scrap allowance are charged. Null clears back to inherit / platform default, which credits nothing."
    },
    "subcontract_overhead_pct": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Subcontract Overhead Pct",
      "description": "Procurement overhead on subcontract work, as a fraction of the subcontract cost (0.05 = 5 %), charged inside the manufacturing cost. Null clears back to inherit / platform default, which adds none."
    },
    "margin_base": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "selbstkosten",
            "netto_selbstkosten"
          ]
        },
        {
          "type": "null"
        }
      ],
      "title": "Margin Base",
      "description": "The base of the profit mark-up. 'selbstkosten' charges margin_pct on the total cost. 'netto_selbstkosten' charges it on the total cost without packaging, freight and duty — the base German public-contract pricing names. Null clears back to inherit / platform default, 'selbstkosten'."
    },
    "factor_first_off": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 10.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Factor First Off",
      "description": "First-article-inspection factor: scales a full inspection into the per-lot first-off time (0 = none, and an explicit 0 is a statement that survives). Null clears back to inherit / platform default."
    },
    "sample_pct_default": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Sample Pct Default",
      "description": "In-process inspection sampling fraction (0..1). An explicit 0 switches sampling off and is a statement that survives; null clears back to inherit / platform default."
    },
    "fai_cost": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 100000.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Fai Cost",
      "description": "Flat first-article-inspection cost per lot, in the environment's currency; null clears back to inherit / platform default."
    },
    "eoq_holding_cost_per_kg_per_year": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 10000.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Eoq Holding Cost Per Kg Per Year",
      "description": "Storage charge for finished stock per kg and year; null clears back to inherit / platform default."
    },
    "holding_cost_rate_per_year": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 1.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Holding Cost Rate Per Year",
      "description": "Imputed yearly interest rate on capital tied up in finished stock (0.08 = 8 %); null clears back to inherit / platform default."
    },
    "ordering_cost_eur_per_order": {
      "anyOf": [
        {
          "type": "number",
          "maximum": 100000.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Ordering Cost Eur Per Order",
      "description": "The buyer's fixed cost of placing and receiving one order, in the environment's currency; null clears back to inherit / platform default (0)."
    }
  },
  "additionalProperties": false,
  "type": "object"
}