feat(membership): add membership_status, resignation_date, fee_included_in_parent
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

- New columns on companies: membership_status (active/resigned/suspended/exempt),
  resignation_date, fee_included_in_parent (boolean)
- Migration 094: sets KORNIX as resigned, PZU resignation_date=2026-03-02,
  links subsidiaries (Pelmar→P&P, Chopin TV→TTM), adds missing companies
  (Maciej Hałas, Markisol as resigned; Fresh Bike, Jantar, WW Glass as
  active subsidiaries)
- Admin fees panel and board view now exclude fee_included_in_parent companies
- Added source Excel file: data/skladki_czlonkowskie_2022_2025.xlsx

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-03-31 11:11:56 +02:00
parent 4157138c2a
commit 4b930ba1b2
5 changed files with 87 additions and 3 deletions

View File

@ -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:

View File

@ -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()}

Binary file not shown.

View File

@ -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))

View File

@ -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;