CoolFace
Apppublic

ali27x/TendersREF

sourceHugging Faceupdated 2mo agoView on Hugging Face
0likes
spec_loader.py134 linesDownload Raw Back to tce
1from __future__ import annotations2 3from dataclasses import dataclass4from pathlib import Path5from typing import Any6import re7 8import openpyxl9 10 11@dataclass(frozen=True)12class MarketDomain:13    id: str14    en: str15    ar: str16 17 18@dataclass(frozen=True)19class MarketSector:20    id: str21    domain_id: str22    en: str23    ar: str24    includes: str = ""25    excludes: str = ""26    notes: str = ""27 28 29@dataclass(frozen=True)30class Nature:31    id: str32    en: str33    ar: str34    scope_required: bool35 36 37@dataclass(frozen=True)38class Scope:39    id: str40    en: str41    ar: str42    applies_to: str43    definition: str44 45 46@dataclass(frozen=True)47class MappingRule:48    term: str49    maps_to: str50    reason: str51    example: str52 53 54@dataclass(frozen=True)55class TcsSpec:56    version: str57    domains: list[MarketDomain]58    sectors: list[MarketSector]59    natures: list[Nature]60    scopes: list[Scope]61    mappings: list[MappingRule]62 63 64def _cell_str(value: Any) -> str:65    return "" if value is None else str(value).strip()66 67 68def _sheet_rows(ws):69    for row in ws.iter_rows(values_only=True):70        yield [_cell_str(v) for v in row]71 72 73def load_spec(xlsx_path: str | Path) -> TcsSpec:74    wb = openpyxl.load_workbook(xlsx_path, data_only=True)75 76    dom_ws = wb["02 Market Domains"]77    sec_ws = wb["03 Market Sectors"]78    nat_ws = wb["04 Nature"]79    scope_ws = wb["05 Scopes"]80    map_ws = wb["07 Special Mappings"]81    overview = wb["01 Overview"]82 83    version = "v1.0"84    for row in _sheet_rows(overview):85        for cell in row:86            if isinstance(cell, str):87                m = re.search(r"v\d+\.\d+", cell)88                if m:89                    version = m.group(0)90                    break91 92    domains: list[MarketDomain] = []93    for row in dom_ws.iter_rows(min_row=4, values_only=True):94        if not row[0]:95            continue96        domains.append(MarketDomain(str(row[0]), _cell_str(row[1]), _cell_str(row[2])))97 98    sectors: list[MarketSector] = []99    for row in sec_ws.iter_rows(min_row=4, values_only=True):100        if not row[0]:101            continue102        sectors.append(103            MarketSector(104                str(row[0]),105                _cell_str(row[1]),106                _cell_str(row[2]),107                _cell_str(row[3]),108                _cell_str(row[6]),109                _cell_str(row[7]),110                _cell_str(row[9]),111            )112        )113 114    natures: list[Nature] = []115    for row in nat_ws.iter_rows(min_row=4, values_only=True):116        if not row[0]:117            continue118        natures.append(Nature(str(row[0]), _cell_str(row[1]), _cell_str(row[2]), _cell_str(row[4]).lower() == "yes"))119 120    scopes: list[Scope] = []121    for row in scope_ws.iter_rows(min_row=4, values_only=True):122        if not row[0]:123            continue124        scopes.append(Scope(str(row[0]), _cell_str(row[1]), _cell_str(row[2]), _cell_str(row[3]), _cell_str(row[4])))125 126    mappings: list[MappingRule] = []127    for row in map_ws.iter_rows(min_row=4, values_only=True):128        if not row[0]:129            continue130        mappings.append(MappingRule(_cell_str(row[0]), _cell_str(row[1]), _cell_str(row[2]), _cell_str(row[3])))131 132    return TcsSpec(version=version, domains=domains, sectors=sectors, natures=natures, scopes=scopes, mappings=mappings)133 134