-- ======================================== -- 給与システム 完全版スキーマ -- Payroll System Complete Schema -- ======================================== -- このスクリプトは既存のテーブルを削除して再作成します -- This script will DROP existing tables and recreate them -- -- 警告: すべてのデータが失われます! -- WARNING: ALL DATA WILL BE LOST! -- ======================================== -- ======================================== -- テーブル削除(依存関係の逆順) -- ======================================== DROP TABLE IF EXISTS payroll_details CASCADE; DROP TABLE IF EXISTS monthly_payroll CASCADE; DROP TABLE IF EXISTS bonus_payments CASCADE; DROP TABLE IF EXISTS income_tax_table CASCADE; DROP TABLE IF EXISTS child_support_contribution_rates CASCADE; DROP TABLE IF EXISTS insurance_rates CASCADE; DROP TABLE IF EXISTS insurance_limit_settings CASCADE; DROP TABLE IF EXISTS dependent_rules CASCADE; DROP TABLE IF EXISTS salary_settings CASCADE; DROP TABLE IF EXISTS dependents CASCADE; DROP TABLE IF EXISTS employees CASCADE; -- ======================================== -- 関数削除 -- ======================================== DROP FUNCTION IF EXISTS update_updated_at() CASCADE; -- ======================================== -- 1. 従業員マスタ (Employees) -- ======================================== CREATE TABLE employees ( employee_id SERIAL PRIMARY KEY, employee_code VARCHAR(20) UNIQUE NOT NULL, name VARCHAR(100) NOT NULL, name_kana VARCHAR(100), birth_date DATE, -- 生年月日(介護保険判定に使用) gender VARCHAR(10), -- 性別 email VARCHAR(100), phone VARCHAR(20), postal_code VARCHAR(10), -- 郵便番号 address VARCHAR(200), -- 住所 hire_date DATE NOT NULL, termination_date DATE, is_active BOOLEAN DEFAULT true, bank_name VARCHAR(100), bank_branch VARCHAR(100), bank_account_number VARCHAR(20), bank_account_type VARCHAR(20), -- 普通/当座 notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE employees IS '従業員マスタ'; COMMENT ON COLUMN employees.employee_code IS '従業員コード'; COMMENT ON COLUMN employees.birth_date IS '生年月日(介護保険料計算に使用)'; COMMENT ON COLUMN employees.gender IS '性別'; COMMENT ON COLUMN employees.postal_code IS '郵便番号'; COMMENT ON COLUMN employees.address IS '住所'; COMMENT ON COLUMN employees.bank_account_type IS '口座種別: 普通/当座'; -- ======================================== -- 2. 扶養家族情報 (Dependents) -- ======================================== CREATE TABLE dependents ( dependent_id SERIAL PRIMARY KEY, employee_id INTEGER NOT NULL REFERENCES employees(employee_id) ON DELETE CASCADE, name VARCHAR(100) NOT NULL, relationship VARCHAR(20) NOT NULL, -- 配偶者/子/親/その他 birth_date DATE, is_spouse BOOLEAN DEFAULT false, is_disabled BOOLEAN DEFAULT false, -- 障害者控除対象 income_amount DECIMAL(12, 2) DEFAULT 0, -- 年間所得 valid_from DATE NOT NULL, valid_to DATE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE dependents IS '扶養家族情報'; COMMENT ON COLUMN dependents.relationship IS '続柄: 配偶者/子/親/その他'; COMMENT ON COLUMN dependents.is_disabled IS '障害者控除対象フラグ'; COMMENT ON COLUMN dependents.income_amount IS '年間所得額'; -- ======================================== -- 3. 給与基本設定 (Salary Settings) -- ======================================== CREATE TABLE salary_settings ( setting_id SERIAL PRIMARY KEY, employee_id INTEGER NOT NULL REFERENCES employees(employee_id) ON DELETE CASCADE, base_salary DECIMAL(12, 2) NOT NULL DEFAULT 0, hourly_rate DECIMAL(10, 2), employment_type VARCHAR(20) NOT NULL, -- 正社員/契約社員/パート/アルバイト payment_type VARCHAR(20) NOT NULL, -- 月給/時給/日給 commute_allowance DECIMAL(12, 2) DEFAULT 0, other_allowance DECIMAL(12, 2) DEFAULT 0, valid_from DATE NOT NULL, valid_to DATE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uc_employee_valid_from UNIQUE (employee_id, valid_from) ); COMMENT ON TABLE salary_settings IS '給与基本設定'; COMMENT ON COLUMN salary_settings.employment_type IS '雇用形態: 正社員/契約社員/パート/アルバイト'; COMMENT ON COLUMN salary_settings.payment_type IS '支給形態: 月給/時給/日給'; -- ======================================== -- 4. 社会保険料率マスタ (Insurance Rates) -- ======================================== CREATE TABLE insurance_rates ( rate_id SERIAL PRIMARY KEY, rate_year INTEGER NOT NULL, -- 適用年度(例:2026) rate_type VARCHAR(50) NOT NULL, -- 健康保険/介護保険/厚生年金/雇用保険/労災保険 calculation_target VARCHAR(20) NOT NULL, -- 給与/賞与 prefecture VARCHAR(50) DEFAULT '東京都', -- 事業所所在地(東京都/神奈川県/千葉県/埼玉県) employee_rate DECIMAL(6, 4) NOT NULL, -- 従業員負担率 employer_rate DECIMAL(6, 4) NOT NULL, -- 会社負担率 care_insurance_age_threshold INTEGER DEFAULT 40, -- 介護保険適用年齢下限 notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uc_rate_year_type_target_prefecture UNIQUE (rate_year, rate_type, calculation_target, prefecture) ); COMMENT ON TABLE insurance_rates IS '社会保険料率マスタ'; COMMENT ON COLUMN insurance_rates.rate_year IS '適用年度'; COMMENT ON COLUMN insurance_rates.rate_type IS '保険種類: 健康保険/介護保険/厚生年金/雇用保険/労災保険'; COMMENT ON COLUMN insurance_rates.calculation_target IS '計算対象: 給与/賞与'; COMMENT ON COLUMN insurance_rates.prefecture IS '事業所所在地'; COMMENT ON COLUMN insurance_rates.employee_rate IS '従業員負担率'; COMMENT ON COLUMN insurance_rates.employer_rate IS '会社負担率'; COMMENT ON COLUMN insurance_rates.care_insurance_age_threshold IS '介護保険適用年齢下限(この年齢以上が対象)'; -- ======================================== -- 4-2. 子ども・子育て拠出金率 (Child Support Contribution Rates) -- ======================================== CREATE TABLE child_support_contribution_rates ( contribution_id SERIAL PRIMARY KEY, rate_year INTEGER NOT NULL, -- 適用年度 income_threshold DECIMAL(12, 2) NOT NULL, -- 所得基準額(標準報酬月額) contribution_rate DECIMAL(6, 4) NOT NULL, -- 拠出金率(事業主負担のみ) notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uc_contribution_year UNIQUE (rate_year) ); COMMENT ON TABLE child_support_contribution_rates IS '子ども・子育て拠出金率'; COMMENT ON COLUMN child_support_contribution_rates.rate_year IS '適用年度'; COMMENT ON COLUMN child_support_contribution_rates.income_threshold IS '所得基準額(標準報酬月額の上限)'; COMMENT ON COLUMN child_support_contribution_rates.contribution_rate IS '拠出金率(事業主のみ負担)'; -- ======================================== -- 5. 社会保険料上限設定 (Insurance Limit Settings) -- ======================================== CREATE TABLE insurance_limit_settings ( limit_id SERIAL PRIMARY KEY, setting_type VARCHAR(50) NOT NULL, -- 健康保険標準報酬月額上限/厚生年金標準報酬月額上限/通勤手当非課税限度額 limit_amount DECIMAL(12, 2) NOT NULL, valid_from DATE NOT NULL, valid_to DATE, notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE insurance_limit_settings IS '社会保険料上限設定'; COMMENT ON COLUMN insurance_limit_settings.setting_type IS '設定種別: 健康保険標準報酬月額上限/厚生年金標準報酬月額上限/通勤手当非課税限度額'; COMMENT ON COLUMN insurance_limit_settings.limit_amount IS '上限額'; -- ======================================== -- 6. 扶養家族判定条件 (Dependent Rules) -- ======================================== CREATE TABLE dependent_rules ( rule_id SERIAL PRIMARY KEY, rule_type VARCHAR(50) NOT NULL, -- 所得限度額/年齢条件/同一生計 rule_value VARCHAR(100) NOT NULL, valid_from DATE NOT NULL, valid_to DATE, description TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE dependent_rules IS '扶養家族判定条件'; COMMENT ON COLUMN dependent_rules.rule_type IS 'ルール種別: 所得限度額/年齢条件/同一生計'; -- ======================================== -- 7. 所得税率表 (Income Tax Table) -- ======================================== CREATE TABLE income_tax_table ( tax_id SERIAL PRIMARY KEY, monthly_income_from DECIMAL(12, 2) NOT NULL, monthly_income_to DECIMAL(12, 2) NOT NULL, dependents_count INTEGER NOT NULL DEFAULT 0, -- 扶養家族人数 tax_amount DECIMAL(10, 2) NOT NULL, valid_from DATE NOT NULL, valid_to DATE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE income_tax_table IS '源泉所得税額表'; COMMENT ON COLUMN income_tax_table.dependents_count IS '扶養家族人数'; -- ======================================== -- 8. 月次給与計算 (Monthly Payroll) -- ======================================== CREATE TABLE monthly_payroll ( payroll_id SERIAL PRIMARY KEY, employee_id INTEGER NOT NULL REFERENCES employees(employee_id), payroll_year INTEGER NOT NULL, payroll_month INTEGER NOT NULL, payment_date DATE NOT NULL, status VARCHAR(20) DEFAULT 'draft', -- draft/calculated/approved/paid -- 勤怠情報 working_days DECIMAL(5, 2) DEFAULT 0, working_hours DECIMAL(6, 2) DEFAULT 0, overtime_hours DECIMAL(6, 2) DEFAULT 0, holiday_hours DECIMAL(6, 2) DEFAULT 0, late_hours DECIMAL(6, 2) DEFAULT 0, absent_days DECIMAL(5, 2) DEFAULT 0, -- 支給項目 base_salary DECIMAL(12, 2) DEFAULT 0, overtime_pay DECIMAL(12, 2) DEFAULT 0, holiday_pay DECIMAL(12, 2) DEFAULT 0, commute_allowance DECIMAL(12, 2) DEFAULT 0, other_allowance DECIMAL(12, 2) DEFAULT 0, total_payment DECIMAL(12, 2) DEFAULT 0, -- 控除項目 health_insurance DECIMAL(12, 2) DEFAULT 0, care_insurance DECIMAL(12, 2) DEFAULT 0, -- 介護保険(40歳以上65歳未満) pension_insurance DECIMAL(12, 2) DEFAULT 0, employment_insurance DECIMAL(12, 2) DEFAULT 0, income_tax DECIMAL(12, 2) DEFAULT 0, resident_tax DECIMAL(12, 2) DEFAULT 0, other_deduction DECIMAL(12, 2) DEFAULT 0, total_deduction DECIMAL(12, 2) DEFAULT 0, -- 差引支給額 net_payment DECIMAL(12, 2) DEFAULT 0, notes TEXT, calculated_at TIMESTAMP, calculated_by VARCHAR(100), approved_at TIMESTAMP, approved_by VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uc_payroll_employee_month UNIQUE (employee_id, payroll_year, payroll_month) ); COMMENT ON TABLE monthly_payroll IS '月次給与計算'; COMMENT ON COLUMN monthly_payroll.status IS 'ステータス: draft/calculated/approved/paid'; COMMENT ON COLUMN monthly_payroll.care_insurance IS '介護保険料(40歳以上65歳未満対象)'; -- ======================================== -- 9. 賞与計算 (Bonus Payments) -- ======================================== CREATE TABLE bonus_payments ( bonus_id SERIAL PRIMARY KEY, employee_id INTEGER NOT NULL REFERENCES employees(employee_id), bonus_year INTEGER NOT NULL, bonus_month INTEGER NOT NULL, bonus_type VARCHAR(50) NOT NULL, -- 夏季賞与/冬季賞与/決算賞与/その他 payment_date DATE NOT NULL, status VARCHAR(20) DEFAULT 'draft', -- draft/calculated/approved/paid -- 支給項目 base_bonus DECIMAL(12, 2) DEFAULT 0, -- 基本賞与額 performance_bonus DECIMAL(12, 2) DEFAULT 0, -- 業績賞与 other_bonus DECIMAL(12, 2) DEFAULT 0, -- その他賞与 total_bonus DECIMAL(12, 2) DEFAULT 0, -- 総支給額 -- 控除項目 health_insurance DECIMAL(12, 2) DEFAULT 0, care_insurance DECIMAL(12, 2) DEFAULT 0, -- 介護保険(40歳以上65歳未満) pension_insurance DECIMAL(12, 2) DEFAULT 0, employment_insurance DECIMAL(12, 2) DEFAULT 0, income_tax DECIMAL(12, 2) DEFAULT 0, -- 賞与所得税 other_deduction DECIMAL(12, 2) DEFAULT 0, total_deduction DECIMAL(12, 2) DEFAULT 0, -- 差引支給額 net_bonus DECIMAL(12, 2) DEFAULT 0, notes TEXT, calculated_at TIMESTAMP, calculated_by VARCHAR(100), approved_at TIMESTAMP, approved_by VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT uc_bonus_employee_payment UNIQUE (employee_id, bonus_year, bonus_month, bonus_type) ); COMMENT ON TABLE bonus_payments IS '賞与計算'; COMMENT ON COLUMN bonus_payments.bonus_type IS '賞与種別: 夏季賞与/冬季賞与/決算賞与/その他'; COMMENT ON COLUMN bonus_payments.status IS 'ステータス: draft/calculated/approved/paid'; -- ======================================== -- 10. 給与明細項目詳細 (Payroll Detail Items) -- ======================================== CREATE TABLE payroll_details ( detail_id SERIAL PRIMARY KEY, payroll_id INTEGER NOT NULL REFERENCES monthly_payroll(payroll_id) ON DELETE CASCADE, item_type VARCHAR(20) NOT NULL, -- payment/deduction item_code VARCHAR(50) NOT NULL, item_name VARCHAR(100) NOT NULL, amount DECIMAL(12, 2) NOT NULL, notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE payroll_details IS '給与明細項目詳細'; COMMENT ON COLUMN payroll_details.item_type IS '項目区分: payment/deduction'; -- ======================================== -- インデックス作成 -- ======================================== CREATE INDEX idx_employees_code ON employees(employee_code); CREATE INDEX idx_employees_active ON employees(is_active); CREATE INDEX idx_dependents_employee ON dependents(employee_id); CREATE INDEX idx_salary_settings_employee ON salary_settings(employee_id); CREATE INDEX idx_salary_settings_valid ON salary_settings(valid_from, valid_to); CREATE INDEX idx_insurance_rates_year ON insurance_rates(rate_year, rate_type, calculation_target); CREATE INDEX idx_child_support_year ON child_support_contribution_rates(rate_year); CREATE INDEX idx_insurance_limits_valid ON insurance_limit_settings(valid_from, valid_to); CREATE INDEX idx_dependent_rules_valid ON dependent_rules(valid_from, valid_to); CREATE INDEX idx_income_tax_valid ON income_tax_table(valid_from, valid_to); CREATE INDEX idx_payroll_employee_year_month ON monthly_payroll(employee_id, payroll_year, payroll_month); CREATE INDEX idx_payroll_status ON monthly_payroll(status); CREATE INDEX idx_bonus_employee_year ON bonus_payments(employee_id, bonus_year); CREATE INDEX idx_bonus_status ON bonus_payments(status); CREATE INDEX idx_payroll_details_payroll ON payroll_details(payroll_id); -- ======================================== -- トリガー関数: 更新日時の自動更新 -- ======================================== CREATE OR REPLACE FUNCTION update_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ LANGUAGE plpgsql; -- ======================================== -- トリガー設定 -- ======================================== CREATE TRIGGER trg_employees_updated_at BEFORE UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER trg_dependents_updated_at BEFORE UPDATE ON dependents FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER trg_salary_settings_updated_at BEFORE UPDATE ON salary_settings FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER trg_insurance_rates_updated_at BEFORE UPDATE ON insurance_rates FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER trg_child_support_updated_at BEFORE UPDATE ON child_support_contribution_rates FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER trg_insurance_limits_updated_at BEFORE UPDATE ON insurance_limit_settings FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER trg_monthly_payroll_updated_at BEFORE UPDATE ON monthly_payroll FOR EACH ROW EXECUTE FUNCTION update_updated_at(); CREATE TRIGGER trg_bonus_payments_updated_at BEFORE UPDATE ON bonus_payments FOR EACH ROW EXECUTE FUNCTION update_updated_at(); -- ======================================== -- 初期データ: 社会保険料率 (2026年度) - 給与計算用 -- ======================================== -- 東京都の健康保険料率(給与) INSERT INTO insurance_rates (rate_year, rate_type, calculation_target, prefecture, employee_rate, employer_rate, care_insurance_age_threshold, notes) VALUES (2026, '健康保険', '給与', '東京都', 0.0500, 0.0500, 40, '健康保険料率 10.00% (労使折半) - 給与'), (2026, '介護保険', '給与', '東京都', 0.0091, 0.0091, 40, '介護保険料率 1.82% (労使折半、40歳以上対象) - 給与'), (2026, '厚生年金', '給与', '東京都', 0.0915, 0.0915, NULL, '厚生年金保険料率 18.30% (労使折半) - 給与'), (2026, '雇用保険', '給与', '東京都', 0.0060, 0.0095, NULL, '雇用保険料率 従業員0.6% 事業主0.95% - 給与'), (2026, '労災保険', '給与', '東京都', 0.0000, 0.0030, NULL, '労災保険料率 事業主のみ0.3% - 給与'); -- 東京都の健康保険料率(賞与) INSERT INTO insurance_rates (rate_year, rate_type, calculation_target, prefecture, employee_rate, employer_rate, care_insurance_age_threshold, notes) VALUES (2026, '健康保険', '賞与', '東京都', 0.0500, 0.0500, 40, '健康保険料率 10.00% (労使折半) - 賞与'), (2026, '介護保険', '賞与', '東京都', 0.0091, 0.0091, 40, '介護保険料率 1.82% (労使折半、40歳以上対象) - 賞与'), (2026, '厚生年金', '賞与', '東京都', 0.0915, 0.0915, NULL, '厚生年金保険料率 18.30% (労使折半) - 賞与'), (2026, '雇用保険', '賞与', '東京都', 0.0060, 0.0095, NULL, '雇用保険料率 従業員0.6% 事業主0.95% - 賞与'); -- ======================================== -- 初期データ: 子ども・子育て拠出金率 (2026年度) -- ======================================== INSERT INTO child_support_contribution_rates (rate_year, income_threshold, contribution_rate, notes) VALUES (2026, 1500000, 0.0036, '子ども・子育て拠出金率 0.36% (事業主のみ負担、標準報酬月額150万円まで)'); -- ======================================== -- 初期データ: 社会保険料上限設定 (2026年度) -- ======================================== INSERT INTO insurance_limit_settings (setting_type, limit_amount, valid_from, notes) VALUES ('健康保険標準報酬月額上限', 1390000, '2026-01-01', '健康保険の標準報酬月額上限(第50級)'), ('厚生年金標準報酬月額上限', 650000, '2026-01-01', '厚生年金保険の標準報酬月額上限(第32級)'), ('通勤手当非課税限度額', 150000, '2026-01-01', '通勤手当の非課税限度額(月額)'); -- ======================================== -- 初期データ: 扶養家族判定条件 (2026年度) -- ======================================== INSERT INTO dependent_rules (rule_type, rule_value, valid_from, description) VALUES ('所得限度額_一般', '480000', '2026-01-01', '一般扶養親族の所得限度額(年間48万円)'), ('所得限度額_配偶者', '480000', '2026-01-01', '配偶者の所得限度額(年間48万円)'), ('所得限度額_配偶者特別', '1330000', '2026-01-01', '配偶者特別控除の所得限度額(年間133万円)'), ('年齢_特定扶養親族', '19-23', '2026-01-01', '特定扶養親族の年齢範囲(19歳以上23歳未満)'), ('年齢_老人扶養親族', '70-', '2026-01-01', '老人扶養親族の年齢(70歳以上)'); -- ======================================== -- スキーマ作成完了 -- ======================================== -- 確認コマンド: -- \dt -- テーブル一覧 -- \d employees -- 従業員テーブル構造 -- \d monthly_payroll -- 月次給与テーブル構造 -- \d bonus_payments -- 賞与テーブル構造 -- -- SELECT * FROM insurance_rates; -- 保険料率確認 -- SELECT * FROM insurance_limit_settings; -- 保険上限確認 -- SELECT * FROM dependent_rules; -- 扶養判定条件確認