-- ============================================================
-- 14_v3_phase2_tables.sql
-- Phase 2: 供应链SRM + MES + 审批流 + 消息推送 + HR + LMS + 营销 + 财务 + 扫码 + 闭环验证 + 安全
-- ============================================================

-- T-201: 供应商主数据
CREATE TABLE IF NOT EXISTS analytics.v3_supplier_master (
  id SERIAL PRIMARY KEY,
  supplier_code TEXT NOT NULL UNIQUE,
  supplier_name TEXT NOT NULL,
  category TEXT,
  grade TEXT DEFAULT '合格',             -- 战略/优选/合格/淘汰
  contact_person TEXT,
  contact_phone TEXT,
  address TEXT,
  delivery_on_time_rate NUMERIC(5,2),
  quality_score NUMERIC(5,2),
  price_score NUMERIC(5,2),
  service_score NUMERIC(5,2),
  food_safety_score NUMERIC(5,2),
  overall_score NUMERIC(5,2),
  is_strategic BOOLEAN DEFAULT false,
  backup_supplier_code TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-203: 采购订单
CREATE TABLE IF NOT EXISTS analytics.v3_purchase_order (
  id SERIAL PRIMARY KEY,
  po_number TEXT NOT NULL UNIQUE,
  supplier_code TEXT NOT NULL,
  store_code TEXT,
  order_date DATE NOT NULL,
  expected_delivery_date DATE,
  actual_delivery_date DATE,
  status TEXT DEFAULT 'draft',           -- draft/submitted/approved/executed/delivered/settled
  total_amount NUMERIC(14,2),
  approval_status TEXT DEFAULT 'pending',
  created_by TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-203: 采购订单明细
CREATE TABLE IF NOT EXISTS analytics.v3_purchase_order_item (
  id SERIAL PRIMARY KEY,
  po_id INT REFERENCES analytics.v3_purchase_order(id) ON DELETE CASCADE,
  sku_code TEXT NOT NULL,
  sku_name TEXT,
  quantity NUMERIC(12,2) NOT NULL,
  unit TEXT,
  unit_price NUMERIC(10,2),
  total_price NUMERIC(14,2),
  received_quantity NUMERIC(12,2)
);

-- T-220: 审批申请
CREATE TABLE IF NOT EXISTS analytics.v3_approval_request (
  id SERIAL PRIMARY KEY,
  request_type TEXT NOT NULL,            -- salary_adjust/purchase/promotion/recipe/supplier_close/store_close
  applicant_id TEXT NOT NULL,
  applicant_name TEXT,
  store_code TEXT,
  status TEXT DEFAULT 'pending',         -- pending/approved/rejected/cancelled
  current_step INT DEFAULT 1,
  total_steps INT,
  request_data JSONB,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-221: 审批步骤
CREATE TABLE IF NOT EXISTS analytics.v3_approval_step (
  id SERIAL PRIMARY KEY,
  request_id INT REFERENCES analytics.v3_approval_request(id) ON DELETE CASCADE,
  step_order INT NOT NULL,
  approver_role TEXT NOT NULL,
  approver_id TEXT,
  approver_name TEXT,
  result TEXT,                            -- approved/rejected/pending
  comment TEXT,
  approved_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-222: 审批规则
CREATE TABLE IF NOT EXISTS analytics.v3_approval_rule (
  id SERIAL PRIMARY KEY,
  request_type TEXT NOT NULL,
  step_order INT NOT NULL,
  approver_role TEXT NOT NULL,
  escalation_condition JSONB,
  escalation_role TEXT,
  is_enabled BOOLEAN DEFAULT true,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  UNIQUE(request_type, step_order)
);

-- T-241: 站内消息
CREATE TABLE IF NOT EXISTS analytics.v3_notification (
  id SERIAL PRIMARY KEY,
  user_id TEXT,
  user_role TEXT,
  title TEXT NOT NULL,
  content TEXT,
  notification_type TEXT,               -- alert/task/report/approval
  related_id INT,
  is_read BOOLEAN DEFAULT false,
  is_handled BOOLEAN DEFAULT false,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-260: 培训课程
CREATE TABLE IF NOT EXISTS analytics.v3_training_course (
  id SERIAL PRIMARY KEY,
  course_name TEXT NOT NULL,
  course_type TEXT,                      -- SOP/技能/食安/管理
  content_url TEXT,
  exam_enabled BOOLEAN DEFAULT false,
  pass_score INT DEFAULT 60,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-261: 学习记录
CREATE TABLE IF NOT EXISTS analytics.v3_learning_record (
  id SERIAL PRIMARY KEY,
  course_id INT REFERENCES analytics.v3_training_course(id) ON DELETE CASCADE,
  employee_name TEXT NOT NULL,
  store_code TEXT,
  progress_pct NUMERIC(5,2) DEFAULT 0,
  completion_status TEXT DEFAULT '未开始', -- 未开始/进行中/已完成/未通过
  exam_score INT,
  started_at TIMESTAMPTZ,
  completed_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-270: 营销活动
CREATE TABLE IF NOT EXISTS analytics.v3_marketing_campaign (
  id SERIAL PRIMARY KEY,
  campaign_name TEXT NOT NULL,
  campaign_type TEXT,                    -- 促销/拉新/召回/品牌
  start_date DATE NOT NULL,
  end_date DATE NOT NULL,
  budget NUMERIC(14,2),
  actual_spend NUMERIC(14,2),
  roi NUMERIC(8,2),
  target_stores TEXT,
  status TEXT DEFAULT 'draft',           -- draft/active/completed/cancelled
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-271: 券码
CREATE TABLE IF NOT EXISTS analytics.v3_coupon (
  id SERIAL PRIMARY KEY,
  campaign_id INT REFERENCES analytics.v3_marketing_campaign(id) ON DELETE CASCADE,
  coupon_code TEXT NOT NULL UNIQUE,
  coupon_type TEXT,                      -- 满减/折扣/赠品
  face_value NUMERIC(10,2),
  min_spend NUMERIC(10,2),
  status TEXT DEFAULT 'unused',          -- unused/used/expired/refunded
  issued_to TEXT,
  used_at TIMESTAMPTZ,
  expiry_date DATE,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-280: 预算管理
CREATE TABLE IF NOT EXISTS analytics.v3_budget (
  id SERIAL PRIMARY KEY,
  year INT NOT NULL,
  month DATE,
  store_code TEXT,
  department TEXT,
  budget_type TEXT,                      -- revenue/expense/capex
  budget_amount NUMERIC(14,2),
  actual_amount NUMERIC(14,2),
  execution_rate NUMERIC(5,2),
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-302: 审计日志
CREATE TABLE IF NOT EXISTS analytics.v3_audit_log (
  id SERIAL PRIMARY KEY,
  user_id TEXT,
  user_name TEXT,
  user_role TEXT,
  action TEXT NOT NULL,                  -- create/update/delete/view
  resource_type TEXT,
  resource_id TEXT,
  details JSONB,
  ip_address TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- T-295: 闭环验证
CREATE TABLE IF NOT EXISTS analytics.v3_loop_verification (
  id SERIAL PRIMARY KEY,
  loop_name TEXT NOT NULL,
  store_code TEXT,
  check_date DATE NOT NULL,
  status TEXT DEFAULT 'open',            -- open/completed/escalated
  completion_rate NUMERIC(5,2),
  cycle_days INT,
  bottleneck TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- 索引
CREATE INDEX IF NOT EXISTS idx_v3_supplier_grade ON analytics.v3_supplier_master(grade);
CREATE INDEX IF NOT EXISTS idx_v3_po_supplier ON analytics.v3_purchase_order(supplier_code);
CREATE INDEX IF NOT EXISTS idx_v3_po_status ON analytics.v3_purchase_order(status);
CREATE INDEX IF NOT EXISTS idx_v3_approval_req_status ON analytics.v3_approval_request(status);
CREATE INDEX IF NOT EXISTS idx_v3_approval_step_req ON analytics.v3_approval_step(request_id);
CREATE INDEX IF NOT EXISTS idx_v3_notification_user ON analytics.v3_notification(user_id);
CREATE INDEX IF NOT EXISTS idx_v3_notification_read ON analytics.v3_notification(is_read);
CREATE INDEX IF NOT EXISTS idx_v3_training_course_type ON analytics.v3_training_course(course_type);
CREATE INDEX IF NOT EXISTS idx_v3_learning_record_course ON analytics.v3_learning_record(course_id);
CREATE INDEX IF NOT EXISTS idx_v3_learning_record_employee ON analytics.v3_learning_record(employee_name);
CREATE INDEX IF NOT EXISTS idx_v3_campaign_status ON analytics.v3_marketing_campaign(status);
CREATE INDEX IF NOT EXISTS idx_v3_coupon_code ON analytics.v3_coupon(coupon_code);
CREATE INDEX IF NOT EXISTS idx_v3_budget_month ON analytics.v3_budget(year, month);
CREATE INDEX IF NOT EXISTS idx_v3_audit_log_user ON analytics.v3_audit_log(user_id);
CREATE INDEX IF NOT EXISTS idx_v3_audit_log_created ON analytics.v3_audit_log(created_at);
CREATE INDEX IF NOT EXISTS idx_v3_loop_verification_date ON analytics.v3_loop_verification(check_date);

-- 初始化默认审批规则
INSERT INTO analytics.v3_approval_rule (request_type, step_order, approver_role, escalation_condition, escalation_role) VALUES
  ('salary_adjust', 1, 'regional', '{"amount": 5000}', 'hq'),
  ('salary_adjust', 2, 'hq', NULL, NULL),
  ('purchase', 1, 'regional', '{"amount": 10000}', 'hq'),
  ('purchase', 2, 'hq', NULL, NULL),
  ('promotion', 1, 'regional', NULL, NULL),
  ('promotion', 2, 'hq', NULL, NULL),
  ('recipe_change', 1, 'hq', '{"cost_change_pct": 5}', 'platform_admin'),
  ('supplier_close', 1, 'hq', NULL, 'platform_admin'),
  ('store_close', 1, 'hq', '{"consecutive_loss_months": 3}', 'platform_admin')
ON CONFLICT DO NOTHING;
