Files
njts-accounting-core/backend/sql/payroll_schema.sql
2026-01-22 01:16:54 +09:00

241 lines
10 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 Schema
-- ========================================
-- 1. 従業員マスタ (Employees)
-- ========================================
CREATE TABLE IF NOT EXISTS 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.bank_account_type IS '口座種別: 普通/当座';
-- ========================================
-- 2. 扶養家族情報 (Dependents)
-- ========================================
CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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,
employment_insurance_eligible BOOLEAN DEFAULT TRUE, -- 雇用保険加入対象かどうか
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 '支給形態: 月給/時給/日給';
COMMENT ON COLUMN salary_settings.employment_insurance_eligible IS '雇用保険加入対象: true=対象、false=非対象';
-- ========================================
-- 4. 社会保険料率マスタ (Insurance Rates)
-- ========================================
CREATE TABLE IF NOT EXISTS insurance_rates (
rate_id SERIAL PRIMARY KEY,
rate_type VARCHAR(50) NOT NULL, -- 健康保険/厚生年金/雇用保険/労災保険
employee_rate DECIMAL(6, 4) NOT NULL, -- 従業員負担率
employer_rate DECIMAL(6, 4) 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_rates IS '社会保険料率マスタ';
COMMENT ON COLUMN insurance_rates.rate_type IS '保険種類: 健康保険/厚生年金/雇用保険/労災保険';
COMMENT ON COLUMN insurance_rates.employee_rate IS '従業員負担率';
COMMENT ON COLUMN insurance_rates.employer_rate IS '会社負担率';
-- ========================================
-- 5. 所得税率表 (Income Tax Table)
-- ========================================
CREATE TABLE IF NOT EXISTS 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 '扶養家族人数';
-- ========================================
-- 6. 月次給与計算ヘッダー (Monthly Payroll Header)
-- ========================================
CREATE TABLE IF NOT EXISTS 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歳以上
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';
-- ========================================
-- 7. 給与明細項目詳細 (Payroll Detail Items)
-- ========================================
CREATE TABLE IF NOT EXISTS 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_valid ON insurance_rates(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_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_monthly_payroll_updated_at BEFORE UPDATE ON monthly_payroll
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- ========================================
-- 初期データ: 保険料率 (2026年度)
-- ========================================
INSERT INTO insurance_rates (rate_type, employee_rate, employer_rate, valid_from, notes) VALUES
('健康保険', 0.0500, 0.0500, '2026-01-01', '健康保険料率 10.00% (労使折半)'),
('介護保険', 0.0091, 0.0091, '2026-01-01', '介護保険料率 1.82% (労使折半、40歳以上対象)'),
('厚生年金', 0.0915, 0.0915, '2026-01-01', '厚生年金保険料率 18.30% (労使折半)'),
('雇用保険', 0.0060, 0.0095, '2026-01-01', '雇用保険料率 従業員0.6% 事業主0.95%'),
('労災保険', 0.0000, 0.0030, '2026-01-01', '労災保険料率 事業主のみ0.3%');