You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
7.2 KiB
Python
248 lines
7.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
from typing import Any, Protocol, Sequence
|
|
|
|
|
|
class ExchangeTemplateKind(str, Enum):
|
|
IMPORT = "import"
|
|
EXPORT = "export"
|
|
|
|
|
|
class ExchangeTaskKind(str, Enum):
|
|
IMPORT = "import"
|
|
EXPORT = "export"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ExchangePlaceholder:
|
|
key: str
|
|
label: str
|
|
description: str | None = None
|
|
required: bool = False
|
|
example: str | None = None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ExchangeField:
|
|
key: str
|
|
label: str
|
|
placeholder: str | None = None
|
|
required: bool = False
|
|
example: str | None = None
|
|
width: int | None = None
|
|
format: str | None = None
|
|
source: str | None = None
|
|
target: str | None = None
|
|
options: tuple[tuple[str, str], ...] = ()
|
|
meta: dict[str, Any] = field(default_factory=dict)
|
|
|
|
def workbook_header(self) -> str:
|
|
return self.placeholder or self.label or self.key
|
|
|
|
def export_source_key(self) -> str:
|
|
return self.source or self.key
|
|
|
|
def import_target_key(self) -> str:
|
|
return self.target or self.key
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ExchangeTemplateBinding:
|
|
entity: str
|
|
template_kind: ExchangeTemplateKind
|
|
handler: str | None = None
|
|
description: str | None = None
|
|
default_sheet_name: str | None = None
|
|
default_file_name: str | None = None
|
|
title: str | None = None
|
|
meta: dict[str, Any] = field(default_factory=dict)
|
|
|
|
|
|
class ExchangeTemplateSourceKind(str, Enum):
|
|
LOCAL = "local"
|
|
REMOTE = "remote"
|
|
MAPPING = "mapping"
|
|
CUSTOM = "custom"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ExchangeTemplateSnapshot:
|
|
id: str
|
|
version: str
|
|
template_id: str
|
|
template_kind: ExchangeTemplateKind
|
|
bindings: tuple[ExchangeTemplateBinding, ...] = ()
|
|
published_at: str | None = None
|
|
file_key: str | None = None
|
|
checksum: str | None = None
|
|
fields: tuple[ExchangeField, ...] = ()
|
|
placeholders: tuple[ExchangePlaceholder, ...] = ()
|
|
meta: dict[str, Any] = field(default_factory=dict)
|
|
|
|
def to_plan(self) -> "ExchangePlan":
|
|
meta = dict(self.meta)
|
|
return ExchangePlan(
|
|
template_kind=self.template_kind,
|
|
template_id=self.template_id,
|
|
version_id=self.id,
|
|
version=self.version,
|
|
bindings=self.bindings,
|
|
fields=self.fields,
|
|
placeholders=self.placeholders,
|
|
title=meta.get("title"),
|
|
description=meta.get("description"),
|
|
sheet_name=meta.get("sheet_name"),
|
|
meta=meta,
|
|
)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ExchangePlan:
|
|
template_kind: ExchangeTemplateKind
|
|
template_id: str | None = None
|
|
version_id: str | None = None
|
|
version: str | None = None
|
|
bindings: tuple[ExchangeTemplateBinding, ...] = ()
|
|
fields: tuple[ExchangeField, ...] = ()
|
|
placeholders: tuple[ExchangePlaceholder, ...] = ()
|
|
title: str | None = None
|
|
description: str | None = None
|
|
sheet_name: str | None = None
|
|
meta: dict[str, Any] = field(default_factory=dict)
|
|
|
|
@classmethod
|
|
def from_mapping(
|
|
cls,
|
|
*,
|
|
template_kind: ExchangeTemplateKind | str,
|
|
template_id: str | None = None,
|
|
version_id: str | None = None,
|
|
version: str | None = None,
|
|
bindings: Sequence[ExchangeTemplateBinding] | None = None,
|
|
fields: Sequence[ExchangeField] | None = None,
|
|
placeholders: Sequence[ExchangePlaceholder] | None = None,
|
|
title: str | None = None,
|
|
description: str | None = None,
|
|
sheet_name: str | None = None,
|
|
meta: dict[str, Any] | None = None,
|
|
) -> "ExchangePlan":
|
|
return cls(
|
|
template_kind=ExchangeTemplateKind(template_kind),
|
|
template_id=template_id,
|
|
version_id=version_id,
|
|
version=version,
|
|
bindings=tuple(bindings or ()),
|
|
fields=tuple(fields or ()),
|
|
placeholders=tuple(placeholders or ()),
|
|
title=title,
|
|
description=description,
|
|
sheet_name=sheet_name,
|
|
meta=meta or {},
|
|
)
|
|
|
|
def resolved_meta(self) -> dict[str, Any]:
|
|
meta = dict(self.meta)
|
|
if self.template_id is not None:
|
|
meta.setdefault("template_id", self.template_id)
|
|
if self.version_id is not None:
|
|
meta.setdefault("version_id", self.version_id)
|
|
if self.version is not None:
|
|
meta.setdefault("version", self.version)
|
|
if self.title is not None:
|
|
meta.setdefault("title", self.title)
|
|
if self.description is not None:
|
|
meta.setdefault("description", self.description)
|
|
if self.sheet_name is not None:
|
|
meta.setdefault("sheet_name", self.sheet_name)
|
|
return meta
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ExchangeTemplateSource:
|
|
kind: ExchangeTemplateSourceKind
|
|
template_kind: ExchangeTemplateKind
|
|
template_id: str | None = None
|
|
version_id: str | None = None
|
|
version: str | None = None
|
|
service: str | None = None
|
|
bindings: tuple[ExchangeTemplateBinding, ...] = ()
|
|
fields: tuple[ExchangeField, ...] = ()
|
|
placeholders: tuple[ExchangePlaceholder, ...] = ()
|
|
title: str | None = None
|
|
description: str | None = None
|
|
sheet_name: str | None = None
|
|
meta: dict[str, Any] = field(default_factory=dict)
|
|
|
|
def to_plan(self) -> ExchangePlan:
|
|
meta = dict(self.meta)
|
|
return ExchangePlan(
|
|
template_kind=self.template_kind,
|
|
template_id=self.template_id,
|
|
version_id=self.version_id,
|
|
version=self.version,
|
|
bindings=self.bindings,
|
|
fields=self.fields,
|
|
placeholders=self.placeholders,
|
|
title=self.title,
|
|
description=self.description,
|
|
sheet_name=self.sheet_name,
|
|
meta=meta,
|
|
)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ExchangeTemplate:
|
|
id: str
|
|
code: str
|
|
name: str
|
|
template_kind: ExchangeTemplateKind
|
|
entity: str
|
|
status: str = "draft"
|
|
description: str | None = None
|
|
current_version: str | None = None
|
|
bindings: tuple[ExchangeTemplateBinding, ...] = ()
|
|
fields: tuple[ExchangeField, ...] = ()
|
|
placeholders: tuple[ExchangePlaceholder, ...] = ()
|
|
meta: dict[str, Any] = field(default_factory=dict)
|
|
|
|
def to_plan(self) -> ExchangePlan:
|
|
meta = dict(self.meta)
|
|
return ExchangePlan(
|
|
template_kind=self.template_kind,
|
|
template_id=self.id,
|
|
version_id=self.current_version,
|
|
bindings=self.bindings,
|
|
fields=self.fields,
|
|
placeholders=self.placeholders,
|
|
title=self.name,
|
|
description=self.description,
|
|
sheet_name=meta.get("sheet_name"),
|
|
meta={
|
|
"code": self.code,
|
|
"status": self.status,
|
|
"current_version": self.current_version,
|
|
**meta,
|
|
},
|
|
)
|
|
|
|
|
|
class DataExchangeModule(Protocol):
|
|
name: str
|
|
|
|
def init_app(self, app) -> None:
|
|
...
|
|
|
|
def register_routes(self, app) -> None:
|
|
...
|
|
|
|
def register_permissions(self, app) -> None:
|
|
...
|
|
|
|
def register_menu_seed(self, app) -> None:
|
|
...
|
|
|
|
def register_tasks(self, app) -> None:
|
|
...
|