gigafibre-fsm/scripts/migration/setup_subscription_api.py
louispaulb 101faa21f1 feat: inline editing, search, notifications + full repo cleanup
- InlineField component + useInlineEdit composable for Odoo-style dblclick editing
- Client search by name, account ID, and legacy_customer_id (or_filters)
- SMS/Email notification panel on ContactCard via n8n webhooks
- Ticket reply thread via Communication docs
- All migration scripts (51 files) now tracked
- Client portal and field tech app added to monorepo
- README rewritten with full feature list, migration summary, architecture
- CHANGELOG updated with all recent work
- ROADMAP updated with current completion status
- Removed hardcoded tokens from docs (use $ERP_SERVICE_TOKEN)
- .gitignore updated (docker/, .claude/, exports/, .quasar/)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 07:34:41 -04:00

84 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""
Fix Subscription DocField restrictions so the REST API can update all fields.
Frappe's standard PUT /api/resource/Subscription/{name} silently ignores
fields marked read_only=1, set_only_once=1, etc. These restrictions make
sense for the desk UI but block our Ops frontend from managing subscriptions.
Changes applied (idempotent):
1. status : read_only 1 -> 0 (so we can cancel/reactivate)
2. cancelation_date : read_only 1 -> 0 (set when cancelling)
3. end_date : set_only_once 1 -> 0 (editable for renewals)
4. start_date : set_only_once 1 -> 0 (editable for corrections)
5. follow_calendar_months : set_only_once 1 -> 0
Also disables follow_calendar_months on all subs (conflicts with annual
billing unless end_date is set).
Run via direct PostgreSQL (no bench CLI needed):
python3 scripts/migration/setup_subscription_api.py
"""
import psycopg2
PG = {"host": "db", "port": 5432, "user": "postgres", "password": "123",
"dbname": "_eb65bdc0c4b1b2d6"}
def main():
pg = psycopg2.connect(**PG)
pgc = pg.cursor()
# 1. Remove read_only on status and cancelation_date
pgc.execute("""
UPDATE "tabDocField"
SET read_only = 0
WHERE parent = 'Subscription'
AND fieldname IN ('status', 'cancelation_date')
AND read_only = 1
""")
n1 = pgc.rowcount
print(f" read_only removed: {n1} fields")
# 2. Remove set_only_once on end_date, start_date, follow_calendar_months
pgc.execute("""
UPDATE "tabDocField"
SET set_only_once = 0
WHERE parent = 'Subscription'
AND fieldname IN ('end_date', 'start_date', 'follow_calendar_months')
AND set_only_once = 1
""")
n2 = pgc.rowcount
print(f" set_only_once removed: {n2} fields")
# 3. Disable follow_calendar_months on all subscriptions
# (it requires end_date + monthly billing; breaks annual subs)
pgc.execute("""
UPDATE "tabSubscription"
SET follow_calendar_months = 0
WHERE follow_calendar_months = 1
""")
n3 = pgc.rowcount
print(f" follow_calendar_months disabled on {n3} subscriptions")
# 4. Fix company name (legacy migration used wrong name)
pgc.execute("""
UPDATE "tabSubscription"
SET company = 'TARGO'
WHERE company != 'TARGO' OR company IS NULL
""")
n4 = pgc.rowcount
print(f" company fixed to TARGO on {n4} subscriptions")
pg.commit()
pg.close()
print()
print("Done. Clear Frappe cache to apply DocField changes:")
print(" bench --site <site> clear-cache")
print(" OR restart the backend container")
if __name__ == "__main__":
main()