Merge branch 'develop' of http://114.203.209.83:3000/SamProject/sam-api into develop
This commit is contained in:
@@ -4,13 +4,18 @@
|
||||
|
||||
use App\Helpers\ApiResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Barobill\BarobillBankTransaction;
|
||||
use App\Models\Barobill\BarobillCardTransaction;
|
||||
use App\Models\Barobill\BarobillMember;
|
||||
use App\Services\Barobill\BarobillSoapService;
|
||||
use App\Services\BarobillService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BarobillController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private BarobillService $barobillService
|
||||
private BarobillService $barobillService,
|
||||
private BarobillSoapService $soapService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -19,17 +24,43 @@ public function __construct(
|
||||
public function status()
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
$tenantId = app('tenant_id');
|
||||
$setting = $this->barobillService->getSetting();
|
||||
$member = BarobillMember::withoutGlobalScopes()
|
||||
->where('tenant_id', $tenantId)
|
||||
->first();
|
||||
|
||||
$accountCount = 0;
|
||||
$cardCount = 0;
|
||||
|
||||
if ($member) {
|
||||
$accountCount = BarobillBankTransaction::withoutGlobalScopes()
|
||||
->where('tenant_id', $tenantId)
|
||||
->distinct('bank_account_num')
|
||||
->count('bank_account_num');
|
||||
|
||||
$cardCount = BarobillCardTransaction::withoutGlobalScopes()
|
||||
->where('tenant_id', $tenantId)
|
||||
->distinct('card_num')
|
||||
->count('card_num');
|
||||
}
|
||||
|
||||
return [
|
||||
'bank_service_count' => 0,
|
||||
'account_link_count' => 0,
|
||||
'member' => $setting ? [
|
||||
'bank_service_count' => $accountCount,
|
||||
'account_link_count' => $accountCount,
|
||||
'card_count' => $cardCount,
|
||||
'member' => $member ? [
|
||||
'barobill_id' => $member->barobill_id,
|
||||
'biz_no' => $member->formatted_biz_no,
|
||||
'corp_name' => $member->corp_name,
|
||||
'status' => $member->status,
|
||||
'server_mode' => $member->server_mode ?? 'test',
|
||||
] : ($setting ? [
|
||||
'barobill_id' => $setting->barobill_id,
|
||||
'biz_no' => $setting->corp_num,
|
||||
'status' => $setting->isVerified() ? 'active' : 'inactive',
|
||||
'server_mode' => $this->barobillService->isTestMode() ? 'test' : 'production',
|
||||
] : null,
|
||||
] : null),
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
306
app/Http/Controllers/Api/V1/BarobillSyncController.php
Normal file
306
app/Http/Controllers/Api/V1/BarobillSyncController.php
Normal file
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Helpers\ApiResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Barobill\BarobillMember;
|
||||
use App\Services\Barobill\BarobillBankSyncService;
|
||||
use App\Services\Barobill\BarobillCardSyncService;
|
||||
use App\Services\Barobill\BarobillSoapService;
|
||||
use App\Services\Barobill\HometaxSyncService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BarobillSyncController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private BarobillSoapService $soapService,
|
||||
private BarobillBankSyncService $bankSyncService,
|
||||
private BarobillCardSyncService $cardSyncService,
|
||||
private HometaxSyncService $hometaxSyncService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 수동 은행 동기화
|
||||
*/
|
||||
public function syncBank(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'start_date' => 'nullable|date_format:Ymd',
|
||||
'end_date' => 'nullable|date_format:Ymd',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$tenantId = app('tenant_id');
|
||||
$startDate = $data['start_date'] ?? Carbon::now()->subMonth()->format('Ymd');
|
||||
$endDate = $data['end_date'] ?? Carbon::now()->format('Ymd');
|
||||
|
||||
return $this->bankSyncService->syncIfNeeded($tenantId, $startDate, $endDate);
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 수동 카드 동기화
|
||||
*/
|
||||
public function syncCard(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'start_date' => 'nullable|date_format:Ymd',
|
||||
'end_date' => 'nullable|date_format:Ymd',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$tenantId = app('tenant_id');
|
||||
$startDate = $data['start_date'] ?? Carbon::now()->subMonth()->format('Ymd');
|
||||
$endDate = $data['end_date'] ?? Carbon::now()->format('Ymd');
|
||||
|
||||
return $this->cardSyncService->syncCardTransactions($tenantId, $startDate, $endDate);
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 수동 홈택스 동기화
|
||||
*/
|
||||
public function syncHometax(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'invoices' => 'required|array',
|
||||
'invoices.*.ntsConfirmNum' => 'required|string',
|
||||
'invoice_type' => 'required|in:sales,purchase',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$tenantId = app('tenant_id');
|
||||
|
||||
return $this->hometaxSyncService->syncInvoices(
|
||||
$data['invoices'],
|
||||
$tenantId,
|
||||
$data['invoice_type']
|
||||
);
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 바로빌 등록계좌 목록 (SOAP 실시간)
|
||||
*/
|
||||
public function accounts()
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
$member = $this->getMember();
|
||||
if (! $member) {
|
||||
return ['accounts' => [], 'message' => '바로빌 회원 정보 없음'];
|
||||
}
|
||||
|
||||
$this->soapService->initForMember($member);
|
||||
|
||||
return [
|
||||
'accounts' => $this->bankSyncService->getRegisteredAccounts($member),
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 바로빌 등록카드 목록 (SOAP 실시간)
|
||||
*/
|
||||
public function cards()
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
$member = $this->getMember();
|
||||
if (! $member) {
|
||||
return ['cards' => [], 'message' => '바로빌 회원 정보 없음'];
|
||||
}
|
||||
|
||||
$this->soapService->initForMember($member);
|
||||
|
||||
return [
|
||||
'cards' => $this->cardSyncService->getRegisteredCards($member),
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 인증서 상태 조회 (만료일, 유효성)
|
||||
*/
|
||||
public function certificate()
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
$member = $this->getMember();
|
||||
if (! $member) {
|
||||
return ['certificate' => null, 'message' => '바로빌 회원 정보 없음'];
|
||||
}
|
||||
|
||||
$this->soapService->initForMember($member);
|
||||
$corpNum = $member->biz_no;
|
||||
|
||||
$valid = $this->soapService->checkCertificateValid($corpNum);
|
||||
$expireDate = $this->soapService->getCertificateExpireDate($corpNum);
|
||||
$registDate = $this->soapService->getCertificateRegistDate($corpNum);
|
||||
|
||||
return [
|
||||
'certificate' => [
|
||||
'is_valid' => $valid['success'] && ($valid['data'] ?? 0) >= 0,
|
||||
'expire_date' => $expireDate['success'] ? ($expireDate['data'] ?? null) : null,
|
||||
'regist_date' => $registDate['success'] ? ($registDate['data'] ?? null) : null,
|
||||
],
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 충전잔액 조회
|
||||
*/
|
||||
public function balance()
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
$member = $this->getMember();
|
||||
if (! $member) {
|
||||
return ['balance' => null, 'message' => '바로빌 회원 정보 없음'];
|
||||
}
|
||||
|
||||
$this->soapService->initForMember($member);
|
||||
$result = $this->soapService->getBalanceCostAmount($member->biz_no);
|
||||
|
||||
return [
|
||||
'balance' => $result['success'] ? ($result['data'] ?? 0) : null,
|
||||
'success' => $result['success'],
|
||||
'error' => $result['error'] ?? null,
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 바로빌 회원 등록 (SOAP RegistCorp)
|
||||
*/
|
||||
public function registerMember(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'biz_no' => 'required|string|size:10',
|
||||
'corp_name' => 'required|string',
|
||||
'ceo_name' => 'required|string',
|
||||
'biz_type' => 'nullable|string',
|
||||
'biz_class' => 'nullable|string',
|
||||
'addr' => 'nullable|string',
|
||||
'barobill_id' => 'required|string',
|
||||
'barobill_pwd' => 'required|string',
|
||||
'manager_name' => 'nullable|string',
|
||||
'manager_hp' => 'nullable|string',
|
||||
'manager_email' => 'nullable|email',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$tenantId = app('tenant_id');
|
||||
$this->soapService->initForMember(
|
||||
BarobillMember::withoutGlobalScopes()->where('tenant_id', $tenantId)->first()
|
||||
?? new BarobillMember(['server_mode' => 'test'])
|
||||
);
|
||||
|
||||
$result = $this->soapService->registCorp($data);
|
||||
|
||||
if ($result['success']) {
|
||||
BarobillMember::withoutGlobalScopes()->updateOrCreate(
|
||||
['tenant_id' => $tenantId],
|
||||
[
|
||||
'biz_no' => $data['biz_no'],
|
||||
'corp_name' => $data['corp_name'],
|
||||
'ceo_name' => $data['ceo_name'],
|
||||
'biz_type' => $data['biz_type'] ?? null,
|
||||
'biz_class' => $data['biz_class'] ?? null,
|
||||
'addr' => $data['addr'] ?? null,
|
||||
'barobill_id' => $data['barobill_id'],
|
||||
'barobill_pwd' => $data['barobill_pwd'],
|
||||
'manager_name' => $data['manager_name'] ?? null,
|
||||
'manager_hp' => $data['manager_hp'] ?? null,
|
||||
'manager_email' => $data['manager_email'] ?? null,
|
||||
'status' => 'active',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}, __('message.created'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 바로빌 회원 수정 (SOAP UpdateCorpInfo)
|
||||
*/
|
||||
public function updateMember(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'corp_name' => 'required|string',
|
||||
'ceo_name' => 'required|string',
|
||||
'biz_type' => 'nullable|string',
|
||||
'biz_class' => 'nullable|string',
|
||||
'addr' => 'nullable|string',
|
||||
'manager_name' => 'nullable|string',
|
||||
'manager_hp' => 'nullable|string',
|
||||
'manager_email' => 'nullable|email',
|
||||
]);
|
||||
|
||||
return ApiResponse::handle(function () use ($data) {
|
||||
$member = $this->getMember();
|
||||
if (! $member) {
|
||||
return ['error' => 'NO_MEMBER', 'code' => 404, 'message' => '바로빌 회원 정보 없음'];
|
||||
}
|
||||
|
||||
$this->soapService->initForMember($member);
|
||||
|
||||
$data['biz_no'] = $member->biz_no;
|
||||
$result = $this->soapService->updateCorpInfo($data);
|
||||
|
||||
if ($result['success']) {
|
||||
$member->update([
|
||||
'corp_name' => $data['corp_name'],
|
||||
'ceo_name' => $data['ceo_name'],
|
||||
'biz_type' => $data['biz_type'] ?? $member->biz_type,
|
||||
'biz_class' => $data['biz_class'] ?? $member->biz_class,
|
||||
'addr' => $data['addr'] ?? $member->addr,
|
||||
'manager_name' => $data['manager_name'] ?? $member->manager_name,
|
||||
'manager_hp' => $data['manager_hp'] ?? $member->manager_hp,
|
||||
'manager_email' => $data['manager_email'] ?? $member->manager_email,
|
||||
]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}, __('message.updated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 바로빌 회원 상태 (SOAP GetCorpState)
|
||||
*/
|
||||
public function memberStatus()
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
$member = $this->getMember();
|
||||
if (! $member) {
|
||||
return ['status' => null, 'message' => '바로빌 회원 정보 없음'];
|
||||
}
|
||||
|
||||
$this->soapService->initForMember($member);
|
||||
$result = $this->soapService->getCorpState($member->biz_no);
|
||||
|
||||
return [
|
||||
'member' => [
|
||||
'biz_no' => $member->formatted_biz_no,
|
||||
'corp_name' => $member->corp_name,
|
||||
'status' => $member->status,
|
||||
'server_mode' => $member->server_mode,
|
||||
],
|
||||
'barobill_state' => $result['success'] ? $result['data'] : null,
|
||||
'error' => $result['error'] ?? null,
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 테넌트의 바로빌 회원 조회
|
||||
*/
|
||||
private function getMember(): ?BarobillMember
|
||||
{
|
||||
$tenantId = app('tenant_id');
|
||||
|
||||
return BarobillMember::withoutGlobalScopes()
|
||||
->where('tenant_id', $tenantId)
|
||||
->first();
|
||||
}
|
||||
}
|
||||
79
app/Http/Controllers/Api/V1/BendingController.php
Normal file
79
app/Http/Controllers/Api/V1/BendingController.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Helpers\ApiResponse;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\BendingCodeService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BendingController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly BendingCodeService $service
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 절곡품 코드맵 조회 (캐스케이딩 드롭다운용)
|
||||
*/
|
||||
public function codeMap(): JsonResponse
|
||||
{
|
||||
return ApiResponse::handle(function () {
|
||||
return $this->service->getCodeMap();
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 드롭다운 선택 → 품목 매핑 조회
|
||||
*/
|
||||
public function resolveItem(Request $request): JsonResponse
|
||||
{
|
||||
return ApiResponse::handle(function () use ($request) {
|
||||
$prodCode = $request->query('prod');
|
||||
$specCode = $request->query('spec');
|
||||
$lengthCode = $request->query('length');
|
||||
|
||||
if (! $prodCode || ! $specCode || ! $lengthCode) {
|
||||
return ['error' => 'MISSING_PARAMS', 'code' => 400, 'message' => 'prod, spec, length 파라미터가 필요합니다.'];
|
||||
}
|
||||
|
||||
$item = $this->service->resolveItem($prodCode, $specCode, $lengthCode);
|
||||
|
||||
if (! $item) {
|
||||
return ['error' => 'NOT_MAPPED', 'code' => 404, 'message' => '해당 조합에 매핑된 품목이 없습니다.'];
|
||||
}
|
||||
|
||||
return $item;
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
|
||||
/**
|
||||
* LOT 번호 생성 (프리뷰 + 일련번호 확정)
|
||||
*/
|
||||
public function generateLotNumber(Request $request): JsonResponse
|
||||
{
|
||||
return ApiResponse::handle(function () use ($request) {
|
||||
$prodCode = $request->input('prod_code');
|
||||
$specCode = $request->input('spec_code');
|
||||
$lengthCode = $request->input('length_code');
|
||||
$regDate = $request->input('reg_date', now()->toDateString());
|
||||
|
||||
if (! $prodCode || ! $specCode || ! $lengthCode) {
|
||||
return ['error' => 'MISSING_PARAMS', 'code' => 400, 'message' => 'prod_code, spec_code, length_code가 필요합니다.'];
|
||||
}
|
||||
|
||||
$dateCode = BendingCodeService::generateDateCode($regDate);
|
||||
$lotBase = "{$prodCode}{$specCode}{$dateCode}-{$lengthCode}";
|
||||
$lotNumber = $this->service->generateLotNumber($lotBase);
|
||||
$material = BendingCodeService::getMaterial($prodCode, $specCode);
|
||||
|
||||
return [
|
||||
'lot_base' => $lotBase,
|
||||
'lot_number' => $lotNumber,
|
||||
'date_code' => $dateCode,
|
||||
'material' => $material,
|
||||
];
|
||||
}, __('message.fetched'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user