Files
njts-accounting-core/backend/sql/payroll_schema_complete.sql
2026-01-20 11:15:49 +09:00

437 lines
21 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ========================================
-- 給与システム 完全版スキーマ
-- 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; -- 扶養判定条件確認