Files
sam-api/app/Http/Controllers/Api/V1/PayrollController.php
권혁성 5448f0e57d deploy: 2026-03-12 배포
- feat: [barobill] 바로빌 카드/은행/홈택스 REST API 구현
- feat: [equipment] 설비관리 API 백엔드 구현
- feat: [payroll] 급여관리 계산 엔진 및 일괄 처리 API
- feat: [QMS] 점검표 템플릿 관리 + 로트심사 개선
- feat: [생산/출하] 수주 단위 출하 자동생성 + 상태 흐름 개선
- feat: [receiving] 입고 성적서 파일 연결
- feat: [견적] 제어기 타입 체계 변경
- feat: [email] 테넌트 메일 설정 마이그레이션 및 모델
- feat: [pmis] 시공관리 테이블 마이그레이션
- feat: [R2] 파일 업로드 커맨드 + filesystems 설정
- feat: [배포] Jenkinsfile 롤백 기능 추가
- fix: [approval] SAM API 규칙 준수 코드 개선
- fix: [account-codes] 계정과목 중복 데이터 정리
- fix: [payroll] 일괄 생성 시 삭제된 사용자 건너뛰기
- fix: [db] codebridge DB 분리 후 깨진 FK 제약조건 제거
- refactor: [barobill] 바로빌 연동 코드 전면 개선
2026-03-12 15:20:20 +09:00

286 lines
7.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api\V1;
use App\Helpers\ApiResponse;
use App\Http\Controllers\Controller;
use App\Http\Requests\V1\Payroll\BulkGeneratePayrollRequest;
use App\Http\Requests\V1\Payroll\CalculatePayrollRequest;
use App\Http\Requests\V1\Payroll\CopyFromPreviousPayrollRequest;
use App\Http\Requests\V1\Payroll\PayPayrollRequest;
use App\Http\Requests\V1\Payroll\StorePayrollJournalRequest;
use App\Http\Requests\V1\Payroll\StorePayrollRequest;
use App\Http\Requests\V1\Payroll\UpdatePayrollRequest;
use App\Http\Requests\V1\Payroll\UpdatePayrollSettingRequest;
use App\Services\ExportService;
use App\Services\PayrollService;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class PayrollController extends Controller
{
public function __construct(
private readonly PayrollService $service,
private readonly ExportService $exportService
) {}
/**
* 급여 목록
*/
public function index(Request $request)
{
$params = $request->only([
'year',
'month',
'user_id',
'status',
'department_id',
'search',
'sort_by',
'sort_dir',
'per_page',
'page',
]);
$payrolls = $this->service->index($params);
return ApiResponse::success($payrolls, __('message.fetched'));
}
/**
* 특정 연월 급여 요약
*/
public function summary(Request $request)
{
$year = (int) $request->input('year', date('Y'));
$month = (int) $request->input('month', date('n'));
$summary = $this->service->summary($year, $month);
return ApiResponse::success($summary, __('message.fetched'));
}
/**
* 급여 등록
*/
public function store(StorePayrollRequest $request)
{
$payroll = $this->service->store($request->validated());
return ApiResponse::success($payroll, __('message.created'), [], 201);
}
/**
* 급여 상세
*/
public function show(int $id)
{
$payroll = $this->service->show($id);
return ApiResponse::success($payroll, __('message.fetched'));
}
/**
* 급여 수정
*/
public function update(int $id, UpdatePayrollRequest $request)
{
$payroll = $this->service->update($id, $request->validated());
return ApiResponse::success($payroll, __('message.updated'));
}
/**
* 급여 삭제
*/
public function destroy(int $id)
{
$this->service->destroy($id);
return ApiResponse::success(null, __('message.deleted'));
}
/**
* 급여 확정
*/
public function confirm(int $id)
{
$payroll = $this->service->confirm($id);
return ApiResponse::success($payroll, __('message.payroll.confirmed'));
}
/**
* 급여 확정 취소
*/
public function unconfirm(int $id)
{
$payroll = $this->service->unconfirm($id);
return ApiResponse::success($payroll, __('message.payroll.unconfirmed'));
}
/**
* 급여 지급 처리
*/
public function pay(int $id, PayPayrollRequest $request)
{
$payroll = $this->service->pay($id, $request->input('withdrawal_id'));
return ApiResponse::success($payroll, __('message.payroll.paid'));
}
/**
* 급여 지급 취소 (슈퍼관리자)
*/
public function unpay(int $id)
{
$payroll = $this->service->unpay($id);
return ApiResponse::success($payroll, __('message.payroll.unpaid'));
}
/**
* 일괄 확정
*/
public function bulkConfirm(Request $request)
{
$year = (int) $request->input('year', date('Y'));
$month = (int) $request->input('month', date('n'));
$count = $this->service->bulkConfirm($year, $month);
return ApiResponse::success(['count' => $count], __('message.payroll.bulk_confirmed'));
}
/**
* 재직사원 일괄 생성
*/
public function bulkGenerate(BulkGeneratePayrollRequest $request)
{
$year = (int) $request->input('year');
$month = (int) $request->input('month');
$result = $this->service->bulkGenerate($year, $month);
return ApiResponse::success($result, __('message.payroll.bulk_generated'));
}
/**
* 전월 급여 복사
*/
public function copyFromPrevious(CopyFromPreviousPayrollRequest $request)
{
$year = (int) $request->input('year');
$month = (int) $request->input('month');
$result = $this->service->copyFromPreviousMonth($year, $month);
return ApiResponse::success($result, __('message.payroll.copied'));
}
/**
* 급여 일괄 계산
*/
public function calculate(CalculatePayrollRequest $request)
{
$year = (int) $request->input('year');
$month = (int) $request->input('month');
$userIds = $request->input('user_ids');
$payrolls = $this->service->calculate($year, $month, $userIds);
return ApiResponse::success($payrolls, __('message.payroll.calculated'));
}
/**
* 급여 계산 미리보기
*/
public function calculatePreview(Request $request)
{
$data = $request->only([
'user_id',
'base_salary',
'overtime_pay',
'bonus',
'allowances',
'deductions',
]);
$result = $this->service->calculatePreview($data);
return ApiResponse::success($result, __('message.calculated'));
}
/**
* 급여명세서 조회
*/
public function payslip(int $id)
{
$payslip = $this->service->payslip($id);
return ApiResponse::success($payslip, __('message.fetched'));
}
/**
* 급여 엑셀 내보내기
*/
public function export(Request $request): BinaryFileResponse
{
$params = $request->only([
'year',
'month',
'status',
'user_id',
'department_id',
'search',
'sort_by',
'sort_dir',
]);
$exportData = $this->service->getExportData($params);
$filename = '급여현황_'.date('Ymd_His');
return $this->exportService->download(
$exportData['data'],
$exportData['headings'],
$filename,
'급여현황'
);
}
/**
* 급여 전표 생성
*/
public function journalEntries(StorePayrollJournalRequest $request)
{
$year = (int) $request->input('year');
$month = (int) $request->input('month');
$entryDate = $request->input('entry_date');
$entry = $this->service->createJournalEntries($year, $month, $entryDate);
return ApiResponse::success($entry, __('message.payroll.journal_created'));
}
/**
* 급여 설정 조회
*/
public function getSettings()
{
$settings = $this->service->getSettings();
return ApiResponse::success($settings, __('message.fetched'));
}
/**
* 급여 설정 수정
*/
public function updateSettings(UpdatePayrollSettingRequest $request)
{
$settings = $this->service->updateSettings($request->validated());
return ApiResponse::success($settings, __('message.updated'));
}
}