How to import per-org ODS files

Per-org ODS files are built by scripts/build_ods_per_org.py and written to tmp/ods_per_org/ (e.g. example_ACR.ods, example_BRN.ods). Each file is a copy of docs/example.ods with Awarded PMs in the WPs+Tasks sheet set to that org’s WBS person-months distributed across the tasks of each WP.

1. Use in LibreOffice (no app import)

Open any file in LibreOffice (or another ODS-capable app):

# Example
libreoffice tmp/ods_per_org/example_ACR.ods

No import into the application is required; the files are normal spreadsheets.

2. Import one per-org ODS into the database

To load the Example project from a specific per-org ODS (e.g. ACR's view) instead of docs/example.ods:

  1. Database must be running and migrated (e.g. Podman PostgreSQL, DATABASE_URL set, uv run python main.py migrate).

  2. Seed from that ODS:

    uv run python scripts/seed_from_ods.py --ods tmp/ods_per_org/example_ACR.ods
    

    Or with short option:

    uv run python scripts/seed_from_ods.py -o tmp/ods_per_org/example_BRN.ods
    
  3. The script extracts content.xml from the given ODS into tmp/seed_import/ and runs load_example_project(app, content_path). The Example project (and its orgs, WPs, WBS, tasks, milestones, deliverables, est_capa) is created or updated from that file. Task Awarded PMs will match the distributed values in that ODS.

Note: Each run overwrites/updates the same Example project. To try another org’s ODS, run seed_from_ods.py --ods path/to/other.ods again.

3. Import all per-org ODS files as separate projects

To create one project per org from all files in tmp/ods_per_org/:

  1. Build the per-org ODS files (if not already done):

    uv run python scripts/build_ods_per_org.py
    
  2. Ensure the database is running and migrated (DATABASE_URL set, uv run python main.py migrate).

  3. Import all:

    uv run python scripts/seed_all_ods_per_org.py
    

    Each example_<Org>.ods is loaded as a project named "Example project (Org)" (e.g. "Example project (ACR)", "Example project (BRN)"). You get one project per file; task Awarded PMs in each project match that org’s distributed WBS values.

    Optional: use another directory:

    uv run python scripts/seed_all_ods_per_org.py --ods-dir /path/to/ods
    

4. Default seed (no per-org file)

To seed from the main example file as before:

uv run python scripts/seed_from_ods.py

This uses docs/example.ods (or docs/content.xml if present).

5. Import when containerised

When using the container image (QA or production), mount the ODS file or directory and run inside the container.

One per-org ODS:

podman compose -f compose.deploy-qa.yml run --rm \
  -v "$(pwd)/tmp/ods_per_org/example_ACR.ods:/app/example_ACR.ods:ro" \
  app-qa python scripts/seed_from_ods.py --ods /app/example_ACR.ods

All per-org ODS files (one project per org): Build the files on the host first (uv run python scripts/build_ods_per_org.py), then mount the directory:

podman compose -f compose.deploy-qa.yml run --rm \
  -v "$(pwd)/tmp/ods_per_org:/app/ods:ro" \
  app-qa python scripts/seed_all_ods_per_org.py --ods-dir /app/ods

Replace compose.deploy-qa.yml and app-qa with compose.deploy-prod.yml and app-prod for production. See Seed projects and calendars for the full container workflow.