feat: [barobill] Fake SOAP 서비스 + 경동 단가 테이블 모델/시더
- BarobillFakeSoapService: SOAP 호출 없이 샘플 데이터 반환 (46개 메서드) - AppServiceProvider: BAROBILL_FAKE_MODE 시 자동 바인딩 전환 - services.php: fake_mode 설정 추가 - KdPriceTable 모델 + KdPriceTableSeeder (5130 레거시 마이그레이션)
This commit is contained in:
341
app/Models/Kyungdong/KdPriceTable.php
Normal file
341
app/Models/Kyungdong/KdPriceTable.php
Normal file
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Kyungdong;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* 경동기업 전용 단가 테이블 모델
|
||||
*
|
||||
* 5130 레거시 price_* 테이블 데이터 조회용
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $tenant_id
|
||||
* @property string $table_type
|
||||
* @property string|null $item_code
|
||||
* @property string|null $item_name
|
||||
* @property string|null $category
|
||||
* @property string|null $spec1
|
||||
* @property string|null $spec2
|
||||
* @property string|null $spec3
|
||||
* @property float $unit_price
|
||||
* @property string $unit
|
||||
* @property array|null $raw_data
|
||||
* @property bool $is_active
|
||||
*/
|
||||
class KdPriceTable extends Model
|
||||
{
|
||||
// 테이블 유형 상수
|
||||
public const TYPE_MOTOR = 'motor';
|
||||
|
||||
public const TYPE_SHAFT = 'shaft';
|
||||
|
||||
public const TYPE_PIPE = 'pipe';
|
||||
|
||||
public const TYPE_ANGLE = 'angle';
|
||||
|
||||
public const TYPE_RAW_MATERIAL = 'raw_material';
|
||||
|
||||
public const TYPE_BDMODELS = 'bdmodels';
|
||||
|
||||
// 경동기업 테넌트 ID
|
||||
public const TENANT_ID = 287;
|
||||
|
||||
protected $table = 'kd_price_tables';
|
||||
|
||||
protected $fillable = [
|
||||
'tenant_id',
|
||||
'table_type',
|
||||
'item_code',
|
||||
'item_name',
|
||||
'category',
|
||||
'spec1',
|
||||
'spec2',
|
||||
'spec3',
|
||||
'unit_price',
|
||||
'unit',
|
||||
'raw_data',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'unit_price' => 'decimal:2',
|
||||
'raw_data' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
// =========================================================================
|
||||
// Scopes
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 테이블 유형으로 필터링
|
||||
*/
|
||||
public function scopeOfType(Builder $query, string $type): Builder
|
||||
{
|
||||
return $query->where('table_type', $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 활성 데이터만
|
||||
*/
|
||||
public function scopeActive(Builder $query): Builder
|
||||
{
|
||||
return $query->where('is_active', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 모터 단가 조회
|
||||
*/
|
||||
public function scopeMotor(Builder $query): Builder
|
||||
{
|
||||
return $query->ofType(self::TYPE_MOTOR)->active();
|
||||
}
|
||||
|
||||
/**
|
||||
* 샤프트 단가 조회
|
||||
*/
|
||||
public function scopeShaft(Builder $query): Builder
|
||||
{
|
||||
return $query->ofType(self::TYPE_SHAFT)->active();
|
||||
}
|
||||
|
||||
/**
|
||||
* 파이프 단가 조회
|
||||
*/
|
||||
public function scopePipeType(Builder $query): Builder
|
||||
{
|
||||
return $query->ofType(self::TYPE_PIPE)->active();
|
||||
}
|
||||
|
||||
/**
|
||||
* 앵글 단가 조회
|
||||
*/
|
||||
public function scopeAngle(Builder $query): Builder
|
||||
{
|
||||
return $query->ofType(self::TYPE_ANGLE)->active();
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Static Query Methods
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 모터 단가 조회
|
||||
*
|
||||
* @param string $motorCapacity 모터 용량 (150K, 300K, 400K, 500K, 600K, 800K, 1000K)
|
||||
*/
|
||||
public static function getMotorPrice(string $motorCapacity): float
|
||||
{
|
||||
$record = self::motor()
|
||||
->where('category', $motorCapacity)
|
||||
->first();
|
||||
|
||||
return (float) ($record?->unit_price ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 제어기 단가 조회
|
||||
*
|
||||
* @param string $controllerType 제어기 타입 (매립형, 노출형, 뒷박스)
|
||||
*/
|
||||
public static function getControllerPrice(string $controllerType): float
|
||||
{
|
||||
$record = self::motor()
|
||||
->where('category', $controllerType)
|
||||
->first();
|
||||
|
||||
return (float) ($record?->unit_price ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 샤프트 단가 조회
|
||||
*
|
||||
* @param string $size 사이즈 (3, 4, 5인치)
|
||||
* @param float $length 길이 (m 단위)
|
||||
*/
|
||||
public static function getShaftPrice(string $size, float $length): float
|
||||
{
|
||||
// 길이를 소수점 1자리 문자열로 변환 (DB 저장 형식: '3.0', '4.0')
|
||||
$lengthStr = number_format($length, 1, '.', '');
|
||||
|
||||
$record = self::shaft()
|
||||
->where('spec1', $size)
|
||||
->where('spec2', $lengthStr)
|
||||
->first();
|
||||
|
||||
return (float) ($record?->unit_price ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 파이프 단가 조회
|
||||
*
|
||||
* @param string $thickness 두께 (1.4 등)
|
||||
* @param int $length 길이 (3000, 6000)
|
||||
*/
|
||||
public static function getPipePrice(string $thickness, int $length): float
|
||||
{
|
||||
$record = self::pipeType()
|
||||
->where('spec1', $thickness)
|
||||
->where('spec2', (string) $length)
|
||||
->first();
|
||||
|
||||
return (float) ($record?->unit_price ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 앵글 단가 조회
|
||||
*
|
||||
* @param string $type 타입 (스크린용, 철재용)
|
||||
* @param string $bracketSize 브라켓크기 (530*320, 600*350, 690*390)
|
||||
* @param string $angleType 앵글타입 (앵글3T, 앵글4T)
|
||||
*/
|
||||
public static function getAnglePrice(string $type, string $bracketSize, string $angleType): float
|
||||
{
|
||||
$record = self::angle()
|
||||
->where('category', $type)
|
||||
->where('spec1', $bracketSize)
|
||||
->where('spec2', $angleType)
|
||||
->first();
|
||||
|
||||
return (float) ($record?->unit_price ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 원자재 단가 조회
|
||||
*
|
||||
* @param string $materialName 원자재명 (실리카, 스크린 등)
|
||||
*/
|
||||
public static function getRawMaterialPrice(string $materialName): float
|
||||
{
|
||||
$record = self::ofType(self::TYPE_RAW_MATERIAL)
|
||||
->active()
|
||||
->where('item_name', $materialName)
|
||||
->first();
|
||||
|
||||
return (float) ($record?->unit_price ?? 0);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// BDmodels 단가 조회 (절곡품)
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* BDmodels 스코프
|
||||
*/
|
||||
public function scopeBdmodels(Builder $query): Builder
|
||||
{
|
||||
return $query->ofType(self::TYPE_BDMODELS)->active();
|
||||
}
|
||||
|
||||
/**
|
||||
* BDmodels 단가 조회 (케이스, 가이드레일, 하단마감재 등)
|
||||
*
|
||||
* @param string $secondItem 부품분류 (케이스, 가이드레일, 하단마감재, L-BAR 등)
|
||||
* @param string|null $modelName 모델코드 (KSS01, KWS01 등)
|
||||
* @param string|null $finishingType 마감재질 (SUS, EGI)
|
||||
* @param string|null $spec 규격 (120*70, 650*550 등)
|
||||
*/
|
||||
public static function getBDModelPrice(
|
||||
string $secondItem,
|
||||
?string $modelName = null,
|
||||
?string $finishingType = null,
|
||||
?string $spec = null
|
||||
): float {
|
||||
$query = self::bdmodels()->where('category', $secondItem);
|
||||
|
||||
if ($modelName) {
|
||||
$query->where('item_code', $modelName);
|
||||
}
|
||||
|
||||
if ($finishingType) {
|
||||
$query->where('spec1', $finishingType);
|
||||
}
|
||||
|
||||
if ($spec) {
|
||||
$query->where('spec2', $spec);
|
||||
}
|
||||
|
||||
$record = $query->first();
|
||||
|
||||
return (float) ($record?->unit_price ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 케이스 단가 조회
|
||||
*
|
||||
* @param string $spec 케이스 규격 (500*380, 650*550 등)
|
||||
*/
|
||||
public static function getCasePrice(string $spec): float
|
||||
{
|
||||
return self::getBDModelPrice('케이스', null, null, $spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* 가이드레일 단가 조회
|
||||
*
|
||||
* @param string $modelName 모델코드 (KSS01 등)
|
||||
* @param string $finishingType 마감재질 (SUS, EGI)
|
||||
* @param string $spec 규격 (120*70, 120*100)
|
||||
*/
|
||||
public static function getGuideRailPrice(string $modelName, string $finishingType, string $spec): float
|
||||
{
|
||||
return self::getBDModelPrice('가이드레일', $modelName, $finishingType, $spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* 하단마감재(하장바) 단가 조회
|
||||
*
|
||||
* @param string $modelName 모델코드
|
||||
* @param string $finishingType 마감재질
|
||||
*/
|
||||
public static function getBottomBarPrice(string $modelName, string $finishingType): float
|
||||
{
|
||||
return self::getBDModelPrice('하단마감재', $modelName, $finishingType);
|
||||
}
|
||||
|
||||
/**
|
||||
* L-BAR 단가 조회
|
||||
*
|
||||
* @param string $modelName 모델코드
|
||||
*/
|
||||
public static function getLBarPrice(string $modelName): float
|
||||
{
|
||||
return self::getBDModelPrice('L-BAR', $modelName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 보강평철 단가 조회
|
||||
*/
|
||||
public static function getFlatBarPrice(): float
|
||||
{
|
||||
return self::getBDModelPrice('보강평철');
|
||||
}
|
||||
|
||||
/**
|
||||
* 케이스 마구리 단가 조회
|
||||
*
|
||||
* @param string $spec 규격
|
||||
*/
|
||||
public static function getCaseCapPrice(string $spec): float
|
||||
{
|
||||
return self::getBDModelPrice('마구리', null, null, $spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* 케이스용 연기차단재 단가 조회
|
||||
*/
|
||||
public static function getCaseSmokeBlockPrice(): float
|
||||
{
|
||||
return self::getBDModelPrice('케이스용 연기차단재');
|
||||
}
|
||||
|
||||
/**
|
||||
* 가이드레일용 연기차단재 단가 조회
|
||||
*/
|
||||
public static function getRailSmokeBlockPrice(): float
|
||||
{
|
||||
return self::getBDModelPrice('가이드레일용 연기차단재');
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,14 @@ public function register(): void
|
||||
DB::enableQueryLog();
|
||||
}
|
||||
}
|
||||
|
||||
// 바로빌 Fake 모드: SOAP 호출 없이 샘플 데이터 반환
|
||||
if (config('services.barobill.fake_mode')) {
|
||||
$this->app->bind(
|
||||
\App\Services\Barobill\BarobillSoapService::class,
|
||||
\App\Services\Barobill\BarobillFakeSoapService::class
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
533
app/Services/Barobill/BarobillFakeSoapService.php
Normal file
533
app/Services/Barobill/BarobillFakeSoapService.php
Normal file
@@ -0,0 +1,533 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Barobill;
|
||||
|
||||
use App\Models\Barobill\BarobillMember;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* 바로빌 Fake SOAP 서비스
|
||||
*
|
||||
* 실제 SOAP 호출 없이 현실적인 샘플 데이터를 반환한다.
|
||||
* .env에서 BAROBILL_FAKE_MODE=true 설정 시 자동 전환.
|
||||
*
|
||||
* 용도:
|
||||
* - 바로빌 계정/인증서 없이 전체 API 흐름 테스트
|
||||
* - React 프론트엔드 독립 개발
|
||||
* - 데모 테넌트 시연
|
||||
* - 자동화 테스트
|
||||
*/
|
||||
class BarobillFakeSoapService extends BarobillSoapService
|
||||
{
|
||||
private bool $initialized = false;
|
||||
|
||||
private string $fakeCorpNum = '6648603713';
|
||||
|
||||
private string $fakeBizNo = '6648603713';
|
||||
|
||||
// ─── 설정 관련 (오버라이드) ───
|
||||
|
||||
public function switchServerMode(bool $isTestMode): self
|
||||
{
|
||||
$this->initialized = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setServerMode(string $mode): self
|
||||
{
|
||||
$this->initialized = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getServerMode(): string
|
||||
{
|
||||
return 'test';
|
||||
}
|
||||
|
||||
public function checkConfiguration(): array
|
||||
{
|
||||
return [
|
||||
'cert_key_set' => true,
|
||||
'corp_num_set' => true,
|
||||
'test_mode' => true,
|
||||
'mode_label' => 'FAKE 모드 (테스트용)',
|
||||
'soap_url' => 'fake://localhost',
|
||||
'config_source' => 'fake',
|
||||
'fake_mode' => true,
|
||||
];
|
||||
}
|
||||
|
||||
public function initForMember(BarobillMember $member): self
|
||||
{
|
||||
$this->fakeCorpNum = $member->biz_no ?? $this->fakeCorpNum;
|
||||
$this->initialized = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// ─── 핵심 SOAP 호출 (가짜 응답) ───
|
||||
|
||||
public function call(string $service, string $method, array $params = []): array
|
||||
{
|
||||
// Fake 모드에서는 모든 call()을 성공으로 반환
|
||||
return ['success' => true, 'data' => 0];
|
||||
}
|
||||
|
||||
// ─── 회원관리 (CORPSTATE) ───
|
||||
|
||||
public function registCorp(array $data): array
|
||||
{
|
||||
return $this->ok(1);
|
||||
}
|
||||
|
||||
public function updateCorpInfo(array $data): array
|
||||
{
|
||||
return $this->ok(1);
|
||||
}
|
||||
|
||||
public function getCorpState(string $corpNum): array
|
||||
{
|
||||
return $this->ok(1); // 1 = 활성 회원
|
||||
}
|
||||
|
||||
// ─── 계좌조회 (BANKACCOUNT) ───
|
||||
|
||||
public function getBankAccounts(string $corpNum, bool $availOnly = true): array
|
||||
{
|
||||
return $this->ok([
|
||||
(object) [
|
||||
'BankAccountNum' => '110-123-456789',
|
||||
'BankCode' => '088',
|
||||
'BankName' => '신한은행',
|
||||
'BankAccountType' => '보통예금',
|
||||
'State' => 1,
|
||||
],
|
||||
(object) [
|
||||
'BankAccountNum' => '123-45-6789012',
|
||||
'BankCode' => '004',
|
||||
'BankName' => '국민은행',
|
||||
'BankAccountType' => '보통예금',
|
||||
'State' => 1,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function getPeriodBankAccountTransLog(
|
||||
string $corpNum, string $id, string $bankAccountNum,
|
||||
string $startDate, string $endDate,
|
||||
int $countPerPage = 1000, int $currentPage = 1
|
||||
): array {
|
||||
$transactions = [];
|
||||
$balance = 50000000;
|
||||
$days = max(1, (int) ((strtotime($endDate) - strtotime($startDate)) / 86400));
|
||||
|
||||
for ($i = 0; $i < min($days, 15); $i++) {
|
||||
$date = date('Ymd', strtotime($startDate) + $i * 86400);
|
||||
$isDeposit = $i % 3 !== 0;
|
||||
$amount = rand(100000, 5000000);
|
||||
$balance += $isDeposit ? $amount : -$amount;
|
||||
|
||||
$transactions[] = (object) [
|
||||
'TransDT' => $date.'120000',
|
||||
'TransDate' => $date,
|
||||
'TransTime' => '120000',
|
||||
'Deposit' => $isDeposit ? $amount : 0,
|
||||
'Withdraw' => $isDeposit ? 0 : $amount,
|
||||
'Balance' => max(0, $balance),
|
||||
'Summary' => $isDeposit ? '입금' : '출금',
|
||||
'Cast' => $this->fakeName(),
|
||||
'Memo' => '',
|
||||
'TransOffice' => $this->fakeCompany(),
|
||||
];
|
||||
}
|
||||
|
||||
return $this->ok($transactions);
|
||||
}
|
||||
|
||||
public function getDailyBankAccountTransLog(
|
||||
string $corpNum, string $id, string $bankAccountNum,
|
||||
string $baseDate, string $transDirection = '',
|
||||
int $countPerPage = 20, int $currentPage = 1
|
||||
): array {
|
||||
return $this->getPeriodBankAccountTransLog($corpNum, $id, $bankAccountNum, $baseDate, $baseDate);
|
||||
}
|
||||
|
||||
public function getMonthlyBankAccountTransLog(
|
||||
string $corpNum, string $id, string $bankAccountNum,
|
||||
string $baseMonth, string $transDirection = '',
|
||||
int $countPerPage = 20, int $currentPage = 1
|
||||
): array {
|
||||
$start = $baseMonth.'01';
|
||||
$end = date('Ymt', strtotime($start));
|
||||
|
||||
return $this->getPeriodBankAccountTransLog($corpNum, $id, $bankAccountNum, $start, $end);
|
||||
}
|
||||
|
||||
public function getBankAccountScrapRequestUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/bank-scrap?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getCertificateRegistUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/cert-regist?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function checkCertificateValid(string $corpNum): array
|
||||
{
|
||||
return $this->ok(1); // 1 = 유효
|
||||
}
|
||||
|
||||
public function getCertificateExpireDate(string $corpNum): array
|
||||
{
|
||||
return $this->ok(date('Ymd', strtotime('+1 year')));
|
||||
}
|
||||
|
||||
public function getCertificateRegistDate(string $corpNum): array
|
||||
{
|
||||
return $this->ok(date('Ymd', strtotime('-6 months')));
|
||||
}
|
||||
|
||||
public function getBalanceCostAmount(string $corpNum): array
|
||||
{
|
||||
return $this->ok(85000); // 충전잔액 85,000원
|
||||
}
|
||||
|
||||
public function getCashChargeUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/cash-charge?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getBankAccountManagementUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/bank-manage?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getBankAccountLogUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/bank-log?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getBarobillUrl(string $corpNum, string $userId, string $userPwd, string $togo = ''): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/main?corp='.$corpNum);
|
||||
}
|
||||
|
||||
// ─── 카드조회 (CARD) ───
|
||||
|
||||
public function getCards(string $corpNum, bool $availOnly = true): array
|
||||
{
|
||||
return $this->ok([
|
||||
(object) [
|
||||
'CardNum' => '5365-12**-****-1234',
|
||||
'CardCompany' => '02',
|
||||
'CardCompanyName' => '삼성카드',
|
||||
'CardType' => '법인',
|
||||
'State' => 1,
|
||||
],
|
||||
(object) [
|
||||
'CardNum' => '4567-89**-****-5678',
|
||||
'CardCompany' => '04',
|
||||
'CardCompanyName' => '현대카드',
|
||||
'CardType' => '법인',
|
||||
'State' => 1,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function registCard(string $corpNum, array $cardData): array
|
||||
{
|
||||
return $this->ok(1);
|
||||
}
|
||||
|
||||
public function updateCard(string $corpNum, array $cardData): array
|
||||
{
|
||||
return $this->ok(1);
|
||||
}
|
||||
|
||||
public function stopCard(string $corpNum, string $cardNum): array
|
||||
{
|
||||
return $this->ok(1);
|
||||
}
|
||||
|
||||
public function cancelStopCard(string $corpNum, string $cardNum): array
|
||||
{
|
||||
return $this->ok(1);
|
||||
}
|
||||
|
||||
public function getPeriodCardLog(
|
||||
string $corpNum, string $id, string $cardNum,
|
||||
string $startDate, string $endDate,
|
||||
int $countPerPage = 1000, int $currentPage = 1
|
||||
): array {
|
||||
$transactions = [];
|
||||
$merchants = ['스타벅스 강남점', '이마트 역삼점', 'GS25 편의점', '교보문고', '쿠팡', '배달의민족', '카카오택시', '주유소'];
|
||||
$days = max(1, (int) ((strtotime($endDate) - strtotime($startDate)) / 86400));
|
||||
|
||||
for ($i = 0; $i < min($days * 2, 20); $i++) {
|
||||
$date = date('Ymd', strtotime($startDate) + intdiv($i, 2) * 86400);
|
||||
$amount = rand(5000, 500000);
|
||||
$supply = (int) round($amount / 1.1);
|
||||
$tax = $amount - $supply;
|
||||
|
||||
$transactions[] = (object) [
|
||||
'UseDT' => $date.sprintf('%02d%02d00', rand(8, 22), rand(0, 59)),
|
||||
'UseDate' => $date,
|
||||
'UseTime' => sprintf('%02d%02d00', rand(8, 22), rand(0, 59)),
|
||||
'ApprovalNum' => sprintf('%08d', rand(10000000, 99999999)),
|
||||
'ApprovalType' => '승인',
|
||||
'ApprovalAmount' => $amount,
|
||||
'Tax' => $tax,
|
||||
'ServiceCharge' => 0,
|
||||
'PaymentPlan' => '일시불',
|
||||
'CurrencyCode' => 'KRW',
|
||||
'MerchantName' => $merchants[array_rand($merchants)],
|
||||
'MerchantBizNum' => sprintf('%010d', rand(1000000000, 9999999999)),
|
||||
'MerchantAddr' => '서울시 강남구',
|
||||
'UseKey' => $cardNum.'|'.$date.'|'.rand(1000, 9999),
|
||||
];
|
||||
}
|
||||
|
||||
return $this->ok($transactions);
|
||||
}
|
||||
|
||||
public function getDailyCardLog(
|
||||
string $corpNum, string $id, string $cardNum,
|
||||
string $baseDate, int $countPerPage = 20, int $currentPage = 1
|
||||
): array {
|
||||
return $this->getPeriodCardLog($corpNum, $id, $cardNum, $baseDate, $baseDate);
|
||||
}
|
||||
|
||||
public function getMonthlyCardLog(
|
||||
string $corpNum, string $id, string $cardNum,
|
||||
string $baseMonth, int $countPerPage = 20, int $currentPage = 1
|
||||
): array {
|
||||
$start = $baseMonth.'01';
|
||||
$end = date('Ymt', strtotime($start));
|
||||
|
||||
return $this->getPeriodCardLog($corpNum, $id, $cardNum, $start, $end);
|
||||
}
|
||||
|
||||
public function getCardScrapRequestUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/card-scrap?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getCardManagementUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/card-manage?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getCardLogUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/card-log?corp='.$corpNum);
|
||||
}
|
||||
|
||||
// ─── 홈택스 (TI) ───
|
||||
|
||||
public function getHomeTaxUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/hometax?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getTaxInvoiceIssueUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/tax-invoice-issue?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getTaxInvoiceListUrl(string $corpNum, string $userId, string $userPwd): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/tax-invoice-list?corp='.$corpNum);
|
||||
}
|
||||
|
||||
// ─── 카카오톡 (KAKAOTALK) ───
|
||||
|
||||
public function getKakaotalkChannels(string $corpNum): array
|
||||
{
|
||||
return $this->ok([
|
||||
(object) [
|
||||
'ChannelId' => '@sam-test',
|
||||
'ChannelName' => 'SAM 테스트 채널',
|
||||
'SearchId' => '@sam-test',
|
||||
'CategoryCode' => 'BIZ',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function getKakaotalkChannelManagementUrl(string $corpNum, string $id): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/kakao-channel?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function getKakaotalkTemplates(string $corpNum, string $channelId): array
|
||||
{
|
||||
return $this->ok([
|
||||
(object) [
|
||||
'TemplateName' => '주문확인',
|
||||
'TemplateCode' => 'TPL001',
|
||||
'TemplateContent' => '#{고객명}님, 주문이 확인되었습니다.',
|
||||
'Status' => 'A',
|
||||
],
|
||||
(object) [
|
||||
'TemplateName' => '발송완료',
|
||||
'TemplateCode' => 'TPL002',
|
||||
'TemplateContent' => '#{고객명}님, 상품이 발송되었습니다.',
|
||||
'Status' => 'A',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function getKakaotalkTemplateManagementUrl(string $corpNum, string $id): array
|
||||
{
|
||||
return $this->ok('https://testws.baroservice.com/fake/kakao-template?corp='.$corpNum);
|
||||
}
|
||||
|
||||
public function sendATKakaotalk(
|
||||
string $corpNum, string $senderId, string $yellowId,
|
||||
string $templateName, string $receiverName, string $receiverNum,
|
||||
string $title, string $message,
|
||||
string $smsMessage = '', string $smsSubject = '',
|
||||
string $smsSenderNum = '', string $reserveDT = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-KKO-'.Str::random(12));
|
||||
}
|
||||
|
||||
public function sendATKakaotalkEx(
|
||||
string $corpNum, string $senderId, string $yellowId,
|
||||
string $templateName, string $receiverName, string $receiverNum,
|
||||
string $title, string $message, array $buttons = [],
|
||||
string $smsMessage = '', string $smsSubject = '',
|
||||
string $smsSenderNum = '', string $reserveDT = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-KKO-'.Str::random(12));
|
||||
}
|
||||
|
||||
public function sendATKakaotalks(
|
||||
string $corpNum, string $senderId, string $yellowId,
|
||||
string $templateName, array $messages, string $reserveDT = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-KKO-BULK-'.Str::random(8));
|
||||
}
|
||||
|
||||
public function sendFTKakaotalk(
|
||||
string $corpNum, string $senderId, string $channelId,
|
||||
string $receiverName, string $receiverNum, string $message,
|
||||
array $buttons = [], string $smsMessage = '', string $smsSubject = '',
|
||||
bool $adYn = false, string $reserveDT = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-FT-'.Str::random(12));
|
||||
}
|
||||
|
||||
public function sendFTKakaotalks(
|
||||
string $corpNum, string $senderId, string $channelId,
|
||||
array $messages, bool $adYn = false, string $reserveDT = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-FT-BULK-'.Str::random(8));
|
||||
}
|
||||
|
||||
public function sendFIKakaotalk(
|
||||
string $corpNum, string $senderId, string $channelId,
|
||||
string $receiverName, string $receiverNum, string $message,
|
||||
string $imageUrl, array $buttons = [],
|
||||
string $smsMessage = '', string $smsSubject = '',
|
||||
bool $adYn = false, string $reserveDT = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-FI-'.Str::random(12));
|
||||
}
|
||||
|
||||
public function sendFWKakaotalk(
|
||||
string $corpNum, string $senderId, string $channelId,
|
||||
string $receiverName, string $receiverNum, string $message,
|
||||
string $imageUrl, array $buttons = [],
|
||||
string $smsMessage = '', string $smsSubject = '',
|
||||
bool $adYn = false, string $reserveDT = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-FW-'.Str::random(12));
|
||||
}
|
||||
|
||||
public function getSendKakaotalk(string $corpNum, string $sendKey): array
|
||||
{
|
||||
return $this->ok((object) [
|
||||
'SendKey' => $sendKey,
|
||||
'SendState' => 3, // 전송 성공
|
||||
'SendStateName' => '전송성공',
|
||||
'SendDT' => now()->format('YmdHis'),
|
||||
'ResultDT' => now()->format('YmdHis'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getSendKakaotalks(string $corpNum, array $sendKeyList): array
|
||||
{
|
||||
$results = [];
|
||||
foreach ($sendKeyList as $key) {
|
||||
$results[] = (object) [
|
||||
'SendKey' => $key,
|
||||
'SendState' => 3,
|
||||
'SendStateName' => '전송성공',
|
||||
];
|
||||
}
|
||||
|
||||
return $this->ok($results);
|
||||
}
|
||||
|
||||
public function cancelReservedKakaotalk(string $corpNum, string $sendKey): array
|
||||
{
|
||||
return $this->ok(1);
|
||||
}
|
||||
|
||||
// ─── SMS ───
|
||||
|
||||
public function sendSMSMessage(
|
||||
string $corpNum, string $senderId, string $fromNumber,
|
||||
string $toName, string $toNumber, string $contents,
|
||||
string $sendDT = '', string $refKey = ''
|
||||
): array {
|
||||
return $this->ok('FAKE-SMS-'.Str::random(12));
|
||||
}
|
||||
|
||||
public function checkSMSFromNumber(string $corpNum, string $fromNumber): array
|
||||
{
|
||||
return $this->ok(1); // 등록된 번호
|
||||
}
|
||||
|
||||
public function getSMSFromNumbers(string $corpNum): array
|
||||
{
|
||||
return $this->ok([
|
||||
(object) ['FromNumber' => '02-1234-5678', 'State' => 1],
|
||||
(object) ['FromNumber' => '010-9876-5432', 'State' => 1],
|
||||
]);
|
||||
}
|
||||
|
||||
public function getSMSSendState(string $corpNum, string $sendKey): array
|
||||
{
|
||||
return $this->ok((object) [
|
||||
'SendKey' => $sendKey,
|
||||
'SendState' => 3,
|
||||
'SendStateName' => '전송성공',
|
||||
'SendDT' => now()->format('YmdHis'),
|
||||
]);
|
||||
}
|
||||
|
||||
// ─── 헬퍼 ───
|
||||
|
||||
private function ok(mixed $data): array
|
||||
{
|
||||
return ['success' => true, 'data' => $data];
|
||||
}
|
||||
|
||||
private function fakeName(): string
|
||||
{
|
||||
$names = ['홍길동', '김영수', '이미영', '박지훈', '최서연', '정태우', '강민지'];
|
||||
|
||||
return $names[array_rand($names)];
|
||||
}
|
||||
|
||||
private function fakeCompany(): string
|
||||
{
|
||||
$companies = ['(주)한국전력', '삼성전자', 'LG화학', '현대건설', '롯데마트', 'CJ물류', 'SKT', '네이버'];
|
||||
|
||||
return $companies[array_rand($companies)];
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,7 @@
|
||||
'cert_key_prod' => env('BAROBILL_CERT_KEY_PROD', ''),
|
||||
'corp_num' => env('BAROBILL_CORP_NUM', ''),
|
||||
'test_mode' => env('BAROBILL_TEST_MODE', true),
|
||||
'fake_mode' => env('BAROBILL_FAKE_MODE', false),
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
565
database/seeders/Kyungdong/KdPriceTableSeeder.php
Normal file
565
database/seeders/Kyungdong/KdPriceTableSeeder.php
Normal file
@@ -0,0 +1,565 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\Kyungdong;
|
||||
|
||||
use App\Models\Kyungdong\KdPriceTable;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* 경동기업 전용 단가 테이블 Seeder
|
||||
*
|
||||
* 5130 레거시 시스템의 price_* 테이블 데이터를 kd_price_tables로 마이그레이션
|
||||
*
|
||||
* 실행: php artisan db:seed --class="Database\Seeders\Kyungdong\KdPriceTableSeeder"
|
||||
*/
|
||||
class KdPriceTableSeeder extends Seeder
|
||||
{
|
||||
private const TENANT_ID = 287;
|
||||
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->command->info('');
|
||||
$this->command->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
$this->command->info('🔧 경동기업 단가 테이블 마이그레이션 (kd_price_tables)');
|
||||
$this->command->info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
|
||||
// 기존 데이터 삭제
|
||||
DB::table('kd_price_tables')->where('tenant_id', self::TENANT_ID)->delete();
|
||||
$this->command->info(' → 기존 데이터 삭제 완료');
|
||||
|
||||
// chandj 연결 가능 여부 확인
|
||||
$chandjAvailable = $this->checkChandjConnection();
|
||||
|
||||
if ($chandjAvailable) {
|
||||
$this->command->info(' → chandj 데이터베이스 연결됨');
|
||||
$this->migrateFromChandj();
|
||||
} else {
|
||||
$this->command->warn(' → chandj 데이터베이스 연결 불가 - 샘플 데이터 사용');
|
||||
$this->insertSampleData();
|
||||
}
|
||||
|
||||
$count = DB::table('kd_price_tables')->where('tenant_id', self::TENANT_ID)->count();
|
||||
$this->command->info('');
|
||||
$this->command->info("✅ 완료: kd_price_tables {$count}건");
|
||||
}
|
||||
|
||||
/**
|
||||
* chandj 데이터베이스 연결 확인
|
||||
*/
|
||||
private function checkChandjConnection(): bool
|
||||
{
|
||||
try {
|
||||
DB::connection('chandj')->getPdo();
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* chandj 데이터베이스에서 마이그레이션
|
||||
*/
|
||||
private function migrateFromChandj(): void
|
||||
{
|
||||
$this->migrateMotorPrices();
|
||||
$this->migrateShaftPrices();
|
||||
$this->migratePipePrices();
|
||||
$this->migrateAnglePrices();
|
||||
$this->migrateRawMaterialPrices();
|
||||
}
|
||||
|
||||
/**
|
||||
* price_motor → kd_price_tables
|
||||
*/
|
||||
private function migrateMotorPrices(): void
|
||||
{
|
||||
$this->command->info('');
|
||||
$this->command->info('📦 [1/5] price_motor 마이그레이션...');
|
||||
|
||||
$priceMotor = DB::connection('chandj')
|
||||
->table('price_motor')
|
||||
->where(function ($q) {
|
||||
$q->where('is_deleted', 0)->orWhereNull('is_deleted');
|
||||
})
|
||||
->orderByDesc('registedate')
|
||||
->first();
|
||||
|
||||
if (! $priceMotor || empty($priceMotor->itemList)) {
|
||||
$this->command->info(' → 데이터 없음');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$itemList = json_decode($priceMotor->itemList, true);
|
||||
if (! is_array($itemList)) {
|
||||
$this->command->info(' → JSON 파싱 실패');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
$now = now();
|
||||
|
||||
foreach ($itemList as $item) {
|
||||
$col1 = $item['col1'] ?? ''; // 전압/카테고리 (220, 380, 제어기 등)
|
||||
$col2 = $item['col2'] ?? ''; // 용량/품목명
|
||||
$salesPrice = (float) str_replace(',', '', $item['col13'] ?? '0');
|
||||
|
||||
if (empty($col2) || $salesPrice <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 카테고리 결정
|
||||
$category = match ($col1) {
|
||||
'220', '380' => $col2, // 모터 용량 (150K, 300K 등)
|
||||
default => $col1, // 제어기, 방화, 방범 등
|
||||
};
|
||||
|
||||
KdPriceTable::create([
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_MOTOR,
|
||||
'item_name' => trim("{$col1} {$col2}"),
|
||||
'category' => $category,
|
||||
'spec1' => $col1,
|
||||
'spec2' => $col2,
|
||||
'unit_price' => $salesPrice,
|
||||
'unit' => 'EA',
|
||||
'raw_data' => $item,
|
||||
'is_active' => true,
|
||||
]);
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->command->info(" → {$count}건 완료");
|
||||
}
|
||||
|
||||
/**
|
||||
* price_shaft → kd_price_tables
|
||||
*/
|
||||
private function migrateShaftPrices(): void
|
||||
{
|
||||
$this->command->info('');
|
||||
$this->command->info('📦 [2/5] price_shaft 마이그레이션...');
|
||||
|
||||
$priceShaft = DB::connection('chandj')
|
||||
->table('price_shaft')
|
||||
->where(function ($q) {
|
||||
$q->where('is_deleted', 0)->orWhereNull('is_deleted');
|
||||
})
|
||||
->orderByDesc('registedate')
|
||||
->first();
|
||||
|
||||
if (! $priceShaft || empty($priceShaft->itemList)) {
|
||||
$this->command->info(' → 데이터 없음');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$itemList = json_decode($priceShaft->itemList, true);
|
||||
if (! is_array($itemList)) {
|
||||
$this->command->info(' → JSON 파싱 실패');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ($itemList as $item) {
|
||||
$size = $item['col4'] ?? ''; // 사이즈 (3, 4, 5인치)
|
||||
$length = $item['col10'] ?? ''; // 길이 (m 단위)
|
||||
$salesPrice = (float) str_replace(',', '', $item['col19'] ?? '0');
|
||||
|
||||
if (empty($size) || $salesPrice <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KdPriceTable::create([
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_SHAFT,
|
||||
'item_name' => "감기샤프트 {$size}인치 {$length}m",
|
||||
'category' => '감기샤프트',
|
||||
'spec1' => $size,
|
||||
'spec2' => $length,
|
||||
'unit_price' => $salesPrice,
|
||||
'unit' => 'EA',
|
||||
'raw_data' => $item,
|
||||
'is_active' => true,
|
||||
]);
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->command->info(" → {$count}건 완료");
|
||||
}
|
||||
|
||||
/**
|
||||
* price_pipe → kd_price_tables
|
||||
*/
|
||||
private function migratePipePrices(): void
|
||||
{
|
||||
$this->command->info('');
|
||||
$this->command->info('📦 [3/5] price_pipe 마이그레이션...');
|
||||
|
||||
$pricePipe = DB::connection('chandj')
|
||||
->table('price_pipe')
|
||||
->where(function ($q) {
|
||||
$q->where('is_deleted', 0)->orWhereNull('is_deleted');
|
||||
})
|
||||
->orderByDesc('registedate')
|
||||
->first();
|
||||
|
||||
if (! $pricePipe || empty($pricePipe->itemList)) {
|
||||
$this->command->info(' → 데이터 없음');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$itemList = json_decode($pricePipe->itemList, true);
|
||||
if (! is_array($itemList)) {
|
||||
$this->command->info(' → JSON 파싱 실패');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ($itemList as $item) {
|
||||
$length = $item['col2'] ?? ''; // 길이 (3000, 6000)
|
||||
$thickness = $item['col4'] ?? ''; // 두께 (1.4)
|
||||
$salesPrice = (float) str_replace(',', '', $item['col8'] ?? '0');
|
||||
|
||||
if (empty($thickness) || $salesPrice <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KdPriceTable::create([
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_PIPE,
|
||||
'item_name' => "각파이프 {$thickness}T {$length}mm",
|
||||
'category' => '각파이프',
|
||||
'spec1' => $thickness,
|
||||
'spec2' => $length,
|
||||
'unit_price' => $salesPrice,
|
||||
'unit' => 'EA',
|
||||
'raw_data' => $item,
|
||||
'is_active' => true,
|
||||
]);
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->command->info(" → {$count}건 완료");
|
||||
}
|
||||
|
||||
/**
|
||||
* price_angle → kd_price_tables
|
||||
*/
|
||||
private function migrateAnglePrices(): void
|
||||
{
|
||||
$this->command->info('');
|
||||
$this->command->info('📦 [4/5] price_angle 마이그레이션...');
|
||||
|
||||
$priceAngle = DB::connection('chandj')
|
||||
->table('price_angle')
|
||||
->where(function ($q) {
|
||||
$q->where('is_deleted', 0)->orWhereNull('is_deleted');
|
||||
})
|
||||
->orderByDesc('registedate')
|
||||
->first();
|
||||
|
||||
if (! $priceAngle || empty($priceAngle->itemList)) {
|
||||
$this->command->info(' → 데이터 없음');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$itemList = json_decode($priceAngle->itemList, true);
|
||||
if (! is_array($itemList)) {
|
||||
$this->command->info(' → JSON 파싱 실패');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ($itemList as $item) {
|
||||
$type = $item['col2'] ?? ''; // 타입 (스크린용, 철재용)
|
||||
$bracketSize = $item['col3'] ?? ''; // 브라켓크기
|
||||
$angleType = $item['col4'] ?? ''; // 앵글타입 (앵글3T, 앵글4T)
|
||||
$thickness = $item['col10'] ?? ''; // 두께
|
||||
$salesPrice = (float) str_replace(',', '', $item['col19'] ?? '0');
|
||||
|
||||
if (empty($type) || $salesPrice <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KdPriceTable::create([
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_ANGLE,
|
||||
'item_name' => "앵글 {$type} {$bracketSize} {$angleType}",
|
||||
'category' => $type,
|
||||
'spec1' => $bracketSize,
|
||||
'spec2' => $angleType,
|
||||
'spec3' => $thickness,
|
||||
'unit_price' => $salesPrice,
|
||||
'unit' => 'EA',
|
||||
'raw_data' => $item,
|
||||
'is_active' => true,
|
||||
]);
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->command->info(" → {$count}건 완료");
|
||||
}
|
||||
|
||||
/**
|
||||
* price_raw_materials → kd_price_tables
|
||||
*/
|
||||
private function migrateRawMaterialPrices(): void
|
||||
{
|
||||
$this->command->info('');
|
||||
$this->command->info('📦 [5/5] price_raw_materials 마이그레이션...');
|
||||
|
||||
$priceRaw = DB::connection('chandj')
|
||||
->table('price_raw_materials')
|
||||
->where(function ($q) {
|
||||
$q->where('is_deleted', 0)->orWhereNull('is_deleted');
|
||||
})
|
||||
->orderByDesc('registedate')
|
||||
->first();
|
||||
|
||||
if (! $priceRaw || empty($priceRaw->itemList)) {
|
||||
$this->command->info(' → 데이터 없음');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$itemList = json_decode($priceRaw->itemList, true);
|
||||
if (! is_array($itemList)) {
|
||||
$this->command->info(' → JSON 파싱 실패');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ($itemList as $item) {
|
||||
$name = $item['col2'] ?? '';
|
||||
$spec = $item['col3'] ?? '';
|
||||
$salesPrice = (float) str_replace(',', '', $item['col19'] ?? $item['col13'] ?? '0');
|
||||
|
||||
if (empty($name) || $salesPrice <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
KdPriceTable::create([
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_RAW_MATERIAL,
|
||||
'item_name' => $name,
|
||||
'category' => '원자재',
|
||||
'spec1' => $spec,
|
||||
'unit_price' => $salesPrice,
|
||||
'unit' => '㎡',
|
||||
'raw_data' => $item,
|
||||
'is_active' => true,
|
||||
]);
|
||||
$count++;
|
||||
}
|
||||
|
||||
$this->command->info(" → {$count}건 완료");
|
||||
}
|
||||
|
||||
/**
|
||||
* chandj 연결 불가 시 샘플 데이터 삽입
|
||||
*/
|
||||
private function insertSampleData(): void
|
||||
{
|
||||
$this->command->info('');
|
||||
$this->command->info('📦 샘플 데이터 삽입 중...');
|
||||
|
||||
// 모터 샘플 데이터 (5130 분석 결과 기반)
|
||||
$motorData = [
|
||||
['category' => '150K', 'spec1' => '220', 'spec2' => '150K', 'unit_price' => 85000],
|
||||
['category' => '300K', 'spec1' => '220', 'spec2' => '300K', 'unit_price' => 120000],
|
||||
['category' => '400K', 'spec1' => '220', 'spec2' => '400K', 'unit_price' => 150000],
|
||||
['category' => '500K', 'spec1' => '220', 'spec2' => '500K', 'unit_price' => 180000],
|
||||
['category' => '600K', 'spec1' => '220', 'spec2' => '600K', 'unit_price' => 220000],
|
||||
['category' => '800K', 'spec1' => '220', 'spec2' => '800K', 'unit_price' => 280000],
|
||||
['category' => '1000K', 'spec1' => '220', 'spec2' => '1000K', 'unit_price' => 350000],
|
||||
['category' => '매립형', 'spec1' => '제어기', 'spec2' => '매립형', 'unit_price' => 45000],
|
||||
['category' => '노출형', 'spec1' => '제어기', 'spec2' => '노출형', 'unit_price' => 55000],
|
||||
['category' => '뒷박스', 'spec1' => '제어기', 'spec2' => '뒷박스', 'unit_price' => 35000],
|
||||
];
|
||||
|
||||
foreach ($motorData as $data) {
|
||||
KdPriceTable::create(array_merge($data, [
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_MOTOR,
|
||||
'item_name' => "모터/제어기 {$data['category']}",
|
||||
'unit' => 'EA',
|
||||
'is_active' => true,
|
||||
]));
|
||||
}
|
||||
$this->command->info(' → 모터/제어기 '.count($motorData).'건');
|
||||
|
||||
// 샤프트 샘플 데이터
|
||||
$shaftData = [
|
||||
['spec1' => '3', 'spec2' => '3.0', 'unit_price' => 45000],
|
||||
['spec1' => '4', 'spec2' => '3.0', 'unit_price' => 55000],
|
||||
['spec1' => '5', 'spec2' => '3.0', 'unit_price' => 65000],
|
||||
['spec1' => '3', 'spec2' => '4.0', 'unit_price' => 60000],
|
||||
['spec1' => '4', 'spec2' => '4.0', 'unit_price' => 75000],
|
||||
['spec1' => '5', 'spec2' => '4.0', 'unit_price' => 90000],
|
||||
];
|
||||
|
||||
foreach ($shaftData as $data) {
|
||||
KdPriceTable::create(array_merge($data, [
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_SHAFT,
|
||||
'item_name' => "감기샤프트 {$data['spec1']}인치 {$data['spec2']}m",
|
||||
'category' => '감기샤프트',
|
||||
'unit' => 'EA',
|
||||
'is_active' => true,
|
||||
]));
|
||||
}
|
||||
$this->command->info(' → 샤프트 '.count($shaftData).'건');
|
||||
|
||||
// 파이프 샘플 데이터
|
||||
$pipeData = [
|
||||
['spec1' => '1.4', 'spec2' => '3000', 'unit_price' => 12000],
|
||||
['spec1' => '1.4', 'spec2' => '6000', 'unit_price' => 24000],
|
||||
];
|
||||
|
||||
foreach ($pipeData as $data) {
|
||||
KdPriceTable::create(array_merge($data, [
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_PIPE,
|
||||
'item_name' => "각파이프 {$data['spec1']}T {$data['spec2']}mm",
|
||||
'category' => '각파이프',
|
||||
'unit' => 'EA',
|
||||
'is_active' => true,
|
||||
]));
|
||||
}
|
||||
$this->command->info(' → 파이프 '.count($pipeData).'건');
|
||||
|
||||
// 앵글 샘플 데이터
|
||||
$angleData = [
|
||||
['category' => '스크린용', 'spec1' => '530*320', 'spec2' => '앵글3T', 'unit_price' => 8000],
|
||||
['category' => '스크린용', 'spec1' => '600*350', 'spec2' => '앵글3T', 'unit_price' => 10000],
|
||||
['category' => '스크린용', 'spec1' => '690*390', 'spec2' => '앵글4T', 'unit_price' => 12000],
|
||||
['category' => '철재용', 'spec1' => '530*320', 'spec2' => '앵글3T', 'unit_price' => 9000],
|
||||
['category' => '철재용', 'spec1' => '600*350', 'spec2' => '앵글3T', 'unit_price' => 11000],
|
||||
['category' => '철재용', 'spec1' => '690*390', 'spec2' => '앵글4T', 'unit_price' => 14000],
|
||||
];
|
||||
|
||||
foreach ($angleData as $data) {
|
||||
KdPriceTable::create(array_merge($data, [
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_ANGLE,
|
||||
'item_name' => "앵글 {$data['category']} {$data['spec1']} {$data['spec2']}",
|
||||
'unit' => 'EA',
|
||||
'is_active' => true,
|
||||
]));
|
||||
}
|
||||
$this->command->info(' → 앵글 '.count($angleData).'건');
|
||||
|
||||
// 원자재 샘플 데이터
|
||||
$rawData = [
|
||||
['item_name' => '실리카', 'spec1' => '스크린용', 'unit_price' => 25000],
|
||||
['item_name' => '불투명', 'spec1' => '스크린용', 'unit_price' => 22000],
|
||||
['item_name' => '화이바원단', 'spec1' => '스크린용', 'unit_price' => 28000],
|
||||
];
|
||||
|
||||
foreach ($rawData as $data) {
|
||||
KdPriceTable::create(array_merge($data, [
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_RAW_MATERIAL,
|
||||
'category' => '원자재',
|
||||
'unit' => '㎡',
|
||||
'is_active' => true,
|
||||
]));
|
||||
}
|
||||
$this->command->info(' → 원자재 '.count($rawData).'건');
|
||||
|
||||
// BDmodels 샘플 데이터 (절곡품)
|
||||
$this->insertBDModelsSampleData();
|
||||
}
|
||||
|
||||
/**
|
||||
* BDmodels 샘플 데이터 삽입 (절곡품)
|
||||
*/
|
||||
private function insertBDModelsSampleData(): void
|
||||
{
|
||||
$bdmodelsData = [
|
||||
// 케이스 (규격별 단가 - 원/m)
|
||||
['category' => '케이스', 'spec2' => '500*380', 'unit_price' => 15000, 'unit' => 'm'],
|
||||
['category' => '케이스', 'spec2' => '550*430', 'unit_price' => 18000, 'unit' => 'm'],
|
||||
['category' => '케이스', 'spec2' => '650*550', 'unit_price' => 22000, 'unit' => 'm'],
|
||||
|
||||
// 케이스 마구리 (규격별 단가 - 원/개)
|
||||
['category' => '마구리', 'spec2' => '500*380', 'unit_price' => 5000, 'unit' => 'EA'],
|
||||
['category' => '마구리', 'spec2' => '550*430', 'unit_price' => 6000, 'unit' => 'EA'],
|
||||
['category' => '마구리', 'spec2' => '650*550', 'unit_price' => 7500, 'unit' => 'EA'],
|
||||
|
||||
// 케이스용 연기차단재 (공통 단가 - 원/m)
|
||||
['category' => '케이스용 연기차단재', 'unit_price' => 3500, 'unit' => 'm'],
|
||||
|
||||
// 가이드레일 (모델+마감+규격별 단가 - 원/m)
|
||||
['category' => '가이드레일', 'item_code' => 'KSS01', 'spec1' => 'SUS', 'spec2' => '120*70', 'unit_price' => 12000, 'unit' => 'm'],
|
||||
['category' => '가이드레일', 'item_code' => 'KSS01', 'spec1' => 'SUS', 'spec2' => '120*100', 'unit_price' => 15000, 'unit' => 'm'],
|
||||
['category' => '가이드레일', 'item_code' => 'KSS01', 'spec1' => 'EGI', 'spec2' => '120*70', 'unit_price' => 10000, 'unit' => 'm'],
|
||||
['category' => '가이드레일', 'item_code' => 'KSS01', 'spec1' => 'EGI', 'spec2' => '120*100', 'unit_price' => 13000, 'unit' => 'm'],
|
||||
['category' => '가이드레일', 'item_code' => 'KWS01', 'spec1' => 'SUS', 'spec2' => '120*70', 'unit_price' => 13000, 'unit' => 'm'],
|
||||
['category' => '가이드레일', 'item_code' => 'KWS01', 'spec1' => 'SUS', 'spec2' => '120*100', 'unit_price' => 16000, 'unit' => 'm'],
|
||||
|
||||
// 가이드레일용 연기차단재 (공통 단가 - 원/m)
|
||||
['category' => '가이드레일용 연기차단재', 'unit_price' => 2500, 'unit' => 'm'],
|
||||
|
||||
// 하단마감재/하장바 (모델+마감별 단가 - 원/m)
|
||||
['category' => '하단마감재', 'item_code' => 'KSS01', 'spec1' => 'SUS', 'unit_price' => 8000, 'unit' => 'm'],
|
||||
['category' => '하단마감재', 'item_code' => 'KSS01', 'spec1' => 'EGI', 'unit_price' => 6500, 'unit' => 'm'],
|
||||
['category' => '하단마감재', 'item_code' => 'KWS01', 'spec1' => 'SUS', 'unit_price' => 8500, 'unit' => 'm'],
|
||||
|
||||
// L-BAR (모델별 단가 - 원/m)
|
||||
['category' => 'L-BAR', 'item_code' => 'KSS01', 'unit_price' => 4500, 'unit' => 'm'],
|
||||
['category' => 'L-BAR', 'item_code' => 'KWS01', 'unit_price' => 5000, 'unit' => 'm'],
|
||||
|
||||
// 보강평철 (공통 단가 - 원/m)
|
||||
['category' => '보강평철', 'unit_price' => 3000, 'unit' => 'm'],
|
||||
];
|
||||
|
||||
foreach ($bdmodelsData as $data) {
|
||||
$itemCode = $data['item_code'] ?? null;
|
||||
$spec1 = $data['spec1'] ?? null;
|
||||
$spec2 = $data['spec2'] ?? null;
|
||||
|
||||
$itemName = $data['category'];
|
||||
if ($itemCode) {
|
||||
$itemName .= " {$itemCode}";
|
||||
}
|
||||
if ($spec1) {
|
||||
$itemName .= " {$spec1}";
|
||||
}
|
||||
if ($spec2) {
|
||||
$itemName .= " {$spec2}";
|
||||
}
|
||||
|
||||
KdPriceTable::create([
|
||||
'tenant_id' => self::TENANT_ID,
|
||||
'table_type' => KdPriceTable::TYPE_BDMODELS,
|
||||
'item_code' => $itemCode,
|
||||
'item_name' => $itemName,
|
||||
'category' => $data['category'],
|
||||
'spec1' => $spec1,
|
||||
'spec2' => $spec2,
|
||||
'unit_price' => $data['unit_price'],
|
||||
'unit' => $data['unit'],
|
||||
'is_active' => true,
|
||||
]);
|
||||
}
|
||||
$this->command->info(' → BDmodels(절곡품) '.count($bdmodelsData).'건');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user