More Shipstation integrations(warehouses)

This commit is contained in:
2026-08-31 15:00:37 -05:00
parent 4c172c1fd5
commit 9651b82415
12 changed files with 337 additions and 139 deletions
+40 -6
View File
@@ -64,6 +64,16 @@ SETTINGS_SCHEMA: Dict[str, tuple[str, str, bool]] = {
"ShipStation",
False,
),
"SHIPSTATION_SIGNIFY_WAREHOUSE_ID": (
"ShipStation Warehouse ID: Signify Health (ship-from location)",
"ShipStation",
False,
),
"SHIPSTATION_OAKSTREET_WAREHOUSE_ID": (
"ShipStation Warehouse ID: Oak Street Health (ship-from location)",
"ShipStation",
False,
),
"COMPANY_SKU_MAP": (
"SKU Prefix -> Company (e.g. SH:Signify Health,OK:Oak Street Health)",
@@ -76,13 +86,14 @@ SETTINGS_SCHEMA: Dict[str, tuple[str, str, bool]] = {
False,
),
"JIRA_TERMINAL_STATUSES": (
"Statuses where we stop re-checking a ticket (comma-separated)",
"ACTIVE_STATUSES": (
"Statuses that count as real active work (comma-separated) - "
"everything else is treated as done",
"Status Tracking",
False,
),
"CANCELLED_STATUSES": (
"Statuses treated as cancelled - highlighted + notified (comma-separated)",
"Statuses treated as cancelled - shown in their own tab (comma-separated)",
"Status Tracking",
False,
),
@@ -109,9 +120,7 @@ DEFAULT_TICKET_NUMBER_REGEX = r"\b[A-Z]{2,6}-\d{3,}\b"
DEFAULT_FULFILLED_WITH_RETURN = "Waiting For Return"
DEFAULT_FULFILLED_WITHOUT_RETURN = "Device Return Not Needed"
DEFAULT_INTAKE_CUTOFF_TIME = "15:30"
DEFAULT_TERMINAL_STATUSES = (
f"Cancelled,{DEFAULT_FULFILLED_WITH_RETURN},{DEFAULT_FULFILLED_WITHOUT_RETURN}"
)
DEFAULT_ACTIVE_STATUSES = "Created"
DEFAULT_CANCELLED_STATUSES = "Cancelled"
@@ -126,6 +135,31 @@ def ensure_env_file_exists() -> None:
ENV_PATH.touch()
def sync_env_with_example() -> None:
"""
Add any key present in .env.example but entirely missing from an
already-existing .env, using .env.example's value as the default -
without touching anything the user already has. .env is gitignored
on purpose (it holds real credentials/field IDs), which means it
never gets updated just by pulling new code - as new settings get
added over time, this is what keeps them from silently sitting blank
until someone notices a feature isn't working. Safe to call every
startup; a no-op once everything's already present.
"""
ensure_env_file_exists()
example_path = PROJECT_ROOT / ".env.example"
if not example_path.exists():
return
example_values = dotenv_values(example_path)
current_values = dotenv_values(ENV_PATH)
for key, example_value in example_values.items():
if key not in current_values:
set_key(str(ENV_PATH), key, example_value or "")
os.environ[key] = example_value or ""
def load_settings() -> Dict[str, str]:
"""Read current values from .env (does not touch os.environ)."""
ensure_env_file_exists()