From 343d7f6256e7864c5f32ba901ce891a22866589e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Wed, 4 Feb 2026 22:43:46 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=EA=B3=A0=EA=B0=9D/=EB=A7=A4=EC=B6=9C/?= =?UTF-8?q?=EB=A7=A4=EC=9E=85/=EC=A0=95=EC=82=B0=20=EB=93=B1=20=EC=9E=AC?= =?UTF-8?q?=EB=AC=B4=20=EA=B4=80=EB=A0=A8=208=EA=B0=9C=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.5 --- ...26_02_04_230001_create_customers_table.php | 36 +++++++++++++++++++ ...2026_02_04_230002_create_incomes_table.php | 32 +++++++++++++++++ ...026_02_04_230003_create_expenses_table.php | 33 +++++++++++++++++ ...2_04_230004_create_sales_records_table.php | 33 +++++++++++++++++ ...26_02_04_230005_create_purchases_table.php | 33 +++++++++++++++++ ...04_230006_create_consulting_fees_table.php | 33 +++++++++++++++++ ...0007_create_customer_settlements_table.php | 33 +++++++++++++++++ ...2_04_230008_create_subscriptions_table.php | 32 +++++++++++++++++ 8 files changed, 265 insertions(+) create mode 100644 database/migrations/2026_02_04_230001_create_customers_table.php create mode 100644 database/migrations/2026_02_04_230002_create_incomes_table.php create mode 100644 database/migrations/2026_02_04_230003_create_expenses_table.php create mode 100644 database/migrations/2026_02_04_230004_create_sales_records_table.php create mode 100644 database/migrations/2026_02_04_230005_create_purchases_table.php create mode 100644 database/migrations/2026_02_04_230006_create_consulting_fees_table.php create mode 100644 database/migrations/2026_02_04_230007_create_customer_settlements_table.php create mode 100644 database/migrations/2026_02_04_230008_create_subscriptions_table.php diff --git a/database/migrations/2026_02_04_230001_create_customers_table.php b/database/migrations/2026_02_04_230001_create_customers_table.php new file mode 100644 index 0000000..b679dff --- /dev/null +++ b/database/migrations/2026_02_04_230001_create_customers_table.php @@ -0,0 +1,36 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->string('name', 100); + $table->string('biz_no', 20)->nullable(); + $table->string('ceo', 50)->nullable(); + $table->string('industry', 50)->nullable(); + $table->string('grade', 20)->default('Silver'); + $table->string('contact', 50)->nullable(); + $table->string('email', 100)->nullable(); + $table->string('address', 200)->nullable(); + $table->string('manager', 50)->nullable(); + $table->string('manager_phone', 20)->nullable(); + $table->string('status', 20)->default('active'); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'grade']); + }); + } + + public function down(): void + { + Schema::dropIfExists('customers'); + } +}; diff --git a/database/migrations/2026_02_04_230002_create_incomes_table.php b/database/migrations/2026_02_04_230002_create_incomes_table.php new file mode 100644 index 0000000..3f9c297 --- /dev/null +++ b/database/migrations/2026_02_04_230002_create_incomes_table.php @@ -0,0 +1,32 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->date('date'); + $table->string('customer', 100); + $table->string('description', 200)->nullable(); + $table->string('category', 50)->default('기타수입'); + $table->bigInteger('amount')->default(0); + $table->string('status', 20)->default('pending'); + $table->string('invoice_no', 50)->nullable(); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'date']); + }); + } + + public function down(): void + { + Schema::dropIfExists('incomes'); + } +}; diff --git a/database/migrations/2026_02_04_230003_create_expenses_table.php b/database/migrations/2026_02_04_230003_create_expenses_table.php new file mode 100644 index 0000000..dcb3b72 --- /dev/null +++ b/database/migrations/2026_02_04_230003_create_expenses_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->date('date'); + $table->string('vendor', 100); + $table->string('description', 200)->nullable(); + $table->string('category', 50)->default('운영비'); + $table->bigInteger('amount')->default(0); + $table->string('status', 20)->default('pending'); + $table->string('payment_method', 30)->default('계좌이체'); + $table->string('invoice_no', 50)->nullable(); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'date']); + }); + } + + public function down(): void + { + Schema::dropIfExists('expenses'); + } +}; diff --git a/database/migrations/2026_02_04_230004_create_sales_records_table.php b/database/migrations/2026_02_04_230004_create_sales_records_table.php new file mode 100644 index 0000000..b17c6f6 --- /dev/null +++ b/database/migrations/2026_02_04_230004_create_sales_records_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->date('date'); + $table->string('customer', 100); + $table->string('project', 200)->nullable(); + $table->string('type', 50)->default('프로젝트'); + $table->bigInteger('amount')->default(0); + $table->bigInteger('vat')->default(0); + $table->string('status', 20)->default('negotiating'); + $table->string('invoice_no', 50)->nullable(); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'date']); + }); + } + + public function down(): void + { + Schema::dropIfExists('sales_records'); + } +}; diff --git a/database/migrations/2026_02_04_230005_create_purchases_table.php b/database/migrations/2026_02_04_230005_create_purchases_table.php new file mode 100644 index 0000000..c2d6664 --- /dev/null +++ b/database/migrations/2026_02_04_230005_create_purchases_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->date('date'); + $table->string('vendor', 100); + $table->string('item', 200)->nullable(); + $table->string('category', 50)->default('운영비'); + $table->bigInteger('amount')->default(0); + $table->bigInteger('vat')->default(0); + $table->string('status', 20)->default('pending'); + $table->string('invoice_no', 50)->nullable(); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'date']); + }); + } + + public function down(): void + { + Schema::dropIfExists('purchases'); + } +}; diff --git a/database/migrations/2026_02_04_230006_create_consulting_fees_table.php b/database/migrations/2026_02_04_230006_create_consulting_fees_table.php new file mode 100644 index 0000000..01078de --- /dev/null +++ b/database/migrations/2026_02_04_230006_create_consulting_fees_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->date('date'); + $table->string('consultant', 50); + $table->string('customer', 100); + $table->string('service', 50)->default('기술 컨설팅'); + $table->integer('hours')->default(0); + $table->integer('hourly_rate')->default(0); + $table->bigInteger('amount')->default(0); + $table->string('status', 20)->default('pending'); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'date']); + }); + } + + public function down(): void + { + Schema::dropIfExists('consulting_fees'); + } +}; diff --git a/database/migrations/2026_02_04_230007_create_customer_settlements_table.php b/database/migrations/2026_02_04_230007_create_customer_settlements_table.php new file mode 100644 index 0000000..91dd4a5 --- /dev/null +++ b/database/migrations/2026_02_04_230007_create_customer_settlements_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->string('period', 7); + $table->string('customer', 100); + $table->bigInteger('total_sales')->default(0); + $table->bigInteger('commission')->default(0); + $table->bigInteger('expense')->default(0); + $table->bigInteger('net_amount')->default(0); + $table->string('status', 20)->default('pending'); + $table->date('settled_date')->nullable(); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + $table->index(['tenant_id', 'period']); + }); + } + + public function down(): void + { + Schema::dropIfExists('customer_settlements'); + } +}; diff --git a/database/migrations/2026_02_04_230008_create_subscriptions_table.php b/database/migrations/2026_02_04_230008_create_subscriptions_table.php new file mode 100644 index 0000000..3df7905 --- /dev/null +++ b/database/migrations/2026_02_04_230008_create_subscriptions_table.php @@ -0,0 +1,32 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->string('customer', 100); + $table->string('plan', 50)->default('Business'); + $table->bigInteger('monthly_fee')->default(0); + $table->string('billing_cycle', 20)->default('monthly'); + $table->date('start_date')->nullable(); + $table->date('next_billing')->nullable(); + $table->string('status', 20)->default('active'); + $table->integer('users')->default(0); + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'status']); + }); + } + + public function down(): void + { + Schema::dropIfExists('subscriptions'); + } +}; From 9c276ed8c390ce5434e32e6962baaa9f616df5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Wed, 4 Feb 2026 22:53:02 +0900 Subject: [PATCH 2/6] =?UTF-8?q?fix:=EA=B8=B0=EC=A1=B4=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EC=B6=A9=EB=8F=8C=20=EB=B0=A9=EC=A7=80=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20hasTable=20=EC=B2=B4=ED=81=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(sales=5Frecords,=20purchases,=20subscriptions)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.5 --- .../2026_02_04_230004_create_sales_records_table.php | 3 +++ .../migrations/2026_02_04_230005_create_purchases_table.php | 3 +++ .../2026_02_04_230008_create_subscriptions_table.php | 3 +++ 3 files changed, 9 insertions(+) diff --git a/database/migrations/2026_02_04_230004_create_sales_records_table.php b/database/migrations/2026_02_04_230004_create_sales_records_table.php index b17c6f6..a1cea1f 100644 --- a/database/migrations/2026_02_04_230004_create_sales_records_table.php +++ b/database/migrations/2026_02_04_230004_create_sales_records_table.php @@ -7,6 +7,9 @@ return new class extends Migration { public function up(): void { + if (Schema::hasTable('sales_records')) { + return; + } Schema::create('sales_records', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('tenant_id'); diff --git a/database/migrations/2026_02_04_230005_create_purchases_table.php b/database/migrations/2026_02_04_230005_create_purchases_table.php index c2d6664..b767c99 100644 --- a/database/migrations/2026_02_04_230005_create_purchases_table.php +++ b/database/migrations/2026_02_04_230005_create_purchases_table.php @@ -7,6 +7,9 @@ return new class extends Migration { public function up(): void { + if (Schema::hasTable('purchases')) { + return; + } Schema::create('purchases', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('tenant_id'); diff --git a/database/migrations/2026_02_04_230008_create_subscriptions_table.php b/database/migrations/2026_02_04_230008_create_subscriptions_table.php index 3df7905..6d37ef2 100644 --- a/database/migrations/2026_02_04_230008_create_subscriptions_table.php +++ b/database/migrations/2026_02_04_230008_create_subscriptions_table.php @@ -7,6 +7,9 @@ return new class extends Migration { public function up(): void { + if (Schema::hasTable('subscriptions')) { + return; + } Schema::create('subscriptions', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('tenant_id'); From 422bad7dfcacbc165e2cba60b497f1afe2db0e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 5 Feb 2026 06:14:18 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=EB=B6=80=EA=B0=80=EC=84=B8=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20vat=5Frecords=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.5 --- ..._02_05_100000_create_vat_records_table.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 database/migrations/2026_02_05_100000_create_vat_records_table.php diff --git a/database/migrations/2026_02_05_100000_create_vat_records_table.php b/database/migrations/2026_02_05_100000_create_vat_records_table.php new file mode 100644 index 0000000..a7a065d --- /dev/null +++ b/database/migrations/2026_02_05_100000_create_vat_records_table.php @@ -0,0 +1,37 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->string('period', 20); // 2026-1H, 2025-2H + $table->string('type', 20)->default('sales'); // sales, purchase + $table->string('partner_name', 100); // 거래처명 + $table->string('invoice_no', 50); // 세금계산서번호 + $table->date('invoice_date')->nullable(); // 발행일 + $table->bigInteger('supply_amount')->default(0); // 공급가액 + $table->bigInteger('vat_amount')->default(0); // 부가세 + $table->bigInteger('total_amount')->default(0); // 합계 + $table->string('status', 20)->default('pending');// pending, filed, paid + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'period']); + $table->index(['tenant_id', 'type']); + }); + } + + public function down(): void + { + Schema::dropIfExists('vat_records'); + } +}; From 00470b7d30bc1df112a012e17db66b35394c9653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 5 Feb 2026 07:43:55 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=EC=9D=BC=EC=9D=BC=EC=9E=90=EA=B8=88?= =?UTF-8?q?=EC=9D=BC=EB=B3=B4=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80=20(daily=5Ffund=5Ftrans?= =?UTF-8?q?actions,=20daily=5Ffund=5Fmemos)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.5 --- ...1_create_daily_fund_transactions_table.php | 36 +++++++++++++++++++ ...5_100002_create_daily_fund_memos_table.php | 28 +++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 database/migrations/2026_02_05_100001_create_daily_fund_transactions_table.php create mode 100644 database/migrations/2026_02_05_100002_create_daily_fund_memos_table.php diff --git a/database/migrations/2026_02_05_100001_create_daily_fund_transactions_table.php b/database/migrations/2026_02_05_100001_create_daily_fund_transactions_table.php new file mode 100644 index 0000000..5182169 --- /dev/null +++ b/database/migrations/2026_02_05_100001_create_daily_fund_transactions_table.php @@ -0,0 +1,36 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->date('transaction_date'); // 거래일 + $table->string('type', 20); // income, expense + $table->string('time', 10)->nullable(); // 시간 (HH:MM) + $table->unsignedBigInteger('account_id')->nullable(); // 계좌ID (corporate_cards 등과 연동 가능) + $table->string('account_name', 50)->nullable(); // 계좌/은행명 (간편 저장용) + $table->string('description', 200); // 적요 + $table->bigInteger('amount')->default(0); // 금액 + $table->string('category', 50)->nullable(); // 카테고리 + $table->string('note', 200)->nullable(); // 비고 + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'transaction_date']); + $table->index(['tenant_id', 'type']); + }); + } + + public function down(): void + { + Schema::dropIfExists('daily_fund_transactions'); + } +}; diff --git a/database/migrations/2026_02_05_100002_create_daily_fund_memos_table.php b/database/migrations/2026_02_05_100002_create_daily_fund_memos_table.php new file mode 100644 index 0000000..36cf021 --- /dev/null +++ b/database/migrations/2026_02_05_100002_create_daily_fund_memos_table.php @@ -0,0 +1,28 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->date('memo_date')->comment('해당 날짜'); + $table->text('memo')->nullable(); + $table->string('author', 50)->nullable(); + $table->timestamps(); + $table->unique(['tenant_id', 'memo_date']); + }); + } + + public function down(): void + { + Schema::dropIfExists('daily_fund_memos'); + } +}; From 2b5ac4c54d3aafd3532cac9f2e48dde0ac0c0604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 5 Feb 2026 07:44:09 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=EB=B2=95=EC=9D=B8=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=20=EA=B1=B0=EB=9E=98=EB=82=B4=EC=97=AD(card=5Ftransactions)=20?= =?UTF-8?q?=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.5 --- ..._100003_create_card_transactions_table.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 database/migrations/2026_02_05_100003_create_card_transactions_table.php diff --git a/database/migrations/2026_02_05_100003_create_card_transactions_table.php b/database/migrations/2026_02_05_100003_create_card_transactions_table.php new file mode 100644 index 0000000..9a55734 --- /dev/null +++ b/database/migrations/2026_02_05_100003_create_card_transactions_table.php @@ -0,0 +1,36 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->unsignedBigInteger('card_id')->nullable(); // corporate_cards.id + $table->date('transaction_date'); // 거래일 + $table->string('time', 10)->nullable(); // 시간 (HH:MM) + $table->string('merchant', 200); // 가맹점명 + $table->string('category', 50)->nullable(); // 카테고리 + $table->bigInteger('amount')->default(0); // 금액 (음수=취소) + $table->string('approval_no', 50)->nullable(); // 승인번호 + $table->string('status', 20)->default('approved'); // approved, cancelled + $table->text('memo')->nullable(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['tenant_id', 'transaction_date']); + $table->index(['tenant_id', 'card_id']); + }); + } + + public function down(): void + { + Schema::dropIfExists('card_transactions'); + } +}; From 9626bca7eb4c95b9677cef45531a265cc651be50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 5 Feb 2026 09:35:04 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:purchases=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=EC=97=90=20MNG=EC=9A=A9=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - date, vendor, item, category, amount, vat, invoice_no, memo 컬럼 추가 - MNG 매입관리 페이지 500 에러 수정용 Co-Authored-By: Claude Opus 4.5 --- ...000_add_mng_columns_to_purchases_table.php | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 database/migrations/2026_02_05_093000_add_mng_columns_to_purchases_table.php diff --git a/database/migrations/2026_02_05_093000_add_mng_columns_to_purchases_table.php b/database/migrations/2026_02_05_093000_add_mng_columns_to_purchases_table.php new file mode 100644 index 0000000..3b55e36 --- /dev/null +++ b/database/migrations/2026_02_05_093000_add_mng_columns_to_purchases_table.php @@ -0,0 +1,49 @@ +date('date')->nullable()->after('purchase_date')->comment('매입일(MNG용)'); + } + if (!Schema::hasColumn('purchases', 'vendor')) { + $table->string('vendor', 100)->nullable()->after('date')->comment('공급자명(MNG용)'); + } + if (!Schema::hasColumn('purchases', 'item')) { + $table->string('item', 200)->nullable()->after('vendor')->comment('품목명(MNG용)'); + } + if (!Schema::hasColumn('purchases', 'category')) { + $table->string('category', 50)->default('운영비')->after('item')->comment('분류(MNG용)'); + } + if (!Schema::hasColumn('purchases', 'amount')) { + $table->bigInteger('amount')->default(0)->after('category')->comment('금액(MNG용)'); + } + if (!Schema::hasColumn('purchases', 'vat')) { + $table->bigInteger('vat')->default(0)->after('amount')->comment('부가세(MNG용)'); + } + if (!Schema::hasColumn('purchases', 'invoice_no')) { + $table->string('invoice_no', 50)->nullable()->after('vat')->comment('인보이스번호(MNG용)'); + } + if (!Schema::hasColumn('purchases', 'memo')) { + $table->text('memo')->nullable()->after('invoice_no')->comment('메모(MNG용)'); + } + }); + } + + public function down(): void + { + Schema::table('purchases', function (Blueprint $table) { + $columns = ['date', 'vendor', 'item', 'category', 'amount', 'vat', 'invoice_no', 'memo']; + foreach ($columns as $col) { + if (Schema::hasColumn('purchases', $col)) { + $table->dropColumn($col); + } + } + }); + } +};