diff --git a/blueprints/admin/routes.py b/blueprints/admin/routes.py index d157f6d..27a0b95 100644 --- a/blueprints/admin/routes.py +++ b/blueprints/admin/routes.py @@ -671,7 +671,10 @@ def admin_fees(): month = request.args.get('month', type=int) status_filter = request.args.get('status', '') - companies = db.query(Company).filter(Company.status == 'active').order_by(Company.name).all() + companies = db.query(Company).filter( + Company.status == 'active', + Company.fee_included_in_parent != True + ).order_by(Company.name).all() fee_query = db.query(MembershipFee).filter(MembershipFee.fee_year == year) if month: @@ -809,7 +812,10 @@ def admin_fees_generate(): ).first() default_fee = fee_config.monthly_amount if fee_config else 100.00 - companies = db.query(Company).filter(Company.status == 'active').all() + companies = db.query(Company).filter( + Company.status == 'active', + Company.fee_included_in_parent != True + ).all() created = 0 for company in companies: diff --git a/blueprints/board/routes.py b/blueprints/board/routes.py index 93b978f..3bf456b 100644 --- a/blueprints/board/routes.py +++ b/blueprints/board/routes.py @@ -781,7 +781,10 @@ def board_fees(): year = request.args.get('year', datetime.now().year, type=int) status_filter = request.args.get('status', '') - companies = db.query(Company).filter(Company.status == 'active').order_by(Company.name).all() + companies = db.query(Company).filter( + Company.status == 'active', + Company.fee_included_in_parent != True + ).order_by(Company.name).all() fee_query = db.query(MembershipFee).filter(MembershipFee.fee_year == year) fees = {(f.company_id, f.fee_month): f for f in fee_query.all()} diff --git a/data/skladki_czlonkowskie_2022_2025.xlsx b/data/skladki_czlonkowskie_2022_2025.xlsx new file mode 100644 index 0000000..da9cd16 Binary files /dev/null and b/data/skladki_czlonkowskie_2022_2025.xlsx differ diff --git a/database.py b/database.py index de5b809..87f6b3c 100644 --- a/database.py +++ b/database.py @@ -779,6 +779,11 @@ class Company(Base): status = Column(String(20)) data_quality = Column(String(20)) + # Membership status: active, resigned, suspended, exempt + membership_status = Column(String(20), default='active') + resignation_date = Column(Date) + fee_included_in_parent = Column(Boolean, default=False) + # Extended company info legal_form = Column(String(100)) parent_organization = Column(String(255)) diff --git a/database/migrations/094_membership_status_fields.sql b/database/migrations/094_membership_status_fields.sql new file mode 100644 index 0000000..42fe77f --- /dev/null +++ b/database/migrations/094_membership_status_fields.sql @@ -0,0 +1,70 @@ +-- Migration 094: Add membership status fields to companies +-- membership_status: active, resigned, suspended, exempt (independent from portal visibility 'status') +-- resignation_date: when company left the chamber +-- fee_included_in_parent: subsidiary whose fees are covered by parent company + +ALTER TABLE companies ADD COLUMN IF NOT EXISTS membership_status VARCHAR(20) DEFAULT 'active'; +ALTER TABLE companies ADD COLUMN IF NOT EXISTS resignation_date DATE; +ALTER TABLE companies ADD COLUMN IF NOT EXISTS fee_included_in_parent BOOLEAN DEFAULT FALSE; + +-- Set membership_status='active' for all currently active companies +UPDATE companies SET membership_status = 'active' WHERE status = 'active' AND membership_status IS NULL; + +-- Set membership_status='resigned' for known inactive companies that resigned +UPDATE companies SET membership_status = 'resigned' WHERE status = 'inactive' AND membership_status IS NULL; + +-- === RESIGNATIONS === + +-- KORNIX (id=82): rezygnacja z końcem 2025 +UPDATE companies SET membership_status = 'resigned', status = 'inactive' WHERE id = 82; + +-- PZU TFI (id=100): rezygnacja 02.03.2026 (already inactive) +UPDATE companies SET membership_status = 'resigned', resignation_date = '2026-03-02' WHERE id = 100; + +-- === SUBSIDIARIES (fee included in parent) === + +-- Pelmar (id=51) → P&P (id=84) +UPDATE companies SET parent_company_id = 84, fee_included_in_parent = TRUE WHERE id = 51; + +-- Chopin Telewizja Kablowa (id=25) → TTM (id=92) +UPDATE companies SET parent_company_id = 92, fee_included_in_parent = TRUE WHERE id = 25; + +-- === NEW COMPANIES: Resigned members === + +-- MACIEJ HAŁAS - rezygnacja +INSERT INTO companies (name, slug, status, membership_status, data_quality) +VALUES ('Maciej Hałas', 'maciej-halas', 'inactive', 'resigned', 'basic') +ON CONFLICT (slug) DO NOTHING; + +-- MARKISOL - rezygnacja 30.01.2025 +INSERT INTO companies (name, slug, status, membership_status, resignation_date, data_quality) +VALUES ('Markisol', 'markisol', 'inactive', 'resigned', '2025-01-30', 'basic') +ON CONFLICT (slug) DO NOTHING; + +-- === NEW COMPANIES: Active subsidiaries === + +-- FRESH BIKE → Eura-Tech (id=34) +INSERT INTO companies (name, slug, status, membership_status, parent_company_id, fee_included_in_parent, data_quality) +VALUES ('Fresh Bike', 'fresh-bike', 'active', 'active', 34, TRUE, 'basic') +ON CONFLICT (slug) DO NOTHING; + +-- JANTAR - centrum handlowe → Eura-Tech (id=34) +INSERT INTO companies (name, slug, status, membership_status, parent_company_id, fee_included_in_parent, data_quality) +VALUES ('Jantar - Centrum Handlowe', 'jantar-centrum-handlowe', 'active', 'active', 34, TRUE, 'basic') +ON CONFLICT (slug) DO NOTHING; + +-- WW GLASS → Lenap Hale (id=83) +INSERT INTO companies (name, slug, status, membership_status, parent_company_id, fee_included_in_parent, data_quality) +VALUES ('WW Glass', 'ww-glass', 'active', 'active', 83, TRUE, 'basic') +ON CONFLICT (slug) DO NOTHING; + +-- === PZU: Waive fees from April 2026 onwards === +UPDATE membership_fees +SET status = 'waived', notes = 'Rezygnacja z członkostwa od 02.03.2026' +WHERE company_id = 100 + AND fee_year = 2026 + AND fee_month >= 4 + AND status IN ('pending', 'overdue'); + +-- Grant permissions +GRANT ALL ON TABLE companies TO nordabiz_app;