feat(statement-branch): 사용자별 거래명세서 공급자 정보 분기 (본사/김포)
Deploy momo-erp / deploy (push) Successful in 1m59s
Deploy momo-erp / deploy (push) Successful in 1m59s
마이그레이션 027: - user_info 에 statement_branch VARCHAR(10) DEFAULT 'HQ' 컬럼 추가 - 기존 사용자 일괄 'HQ' 로 채움 라이브러리: - src/lib/momo-branches.ts 신설 — HQ / KIMPO 두 branch 의 공급자 정보 정의 · HQ: 기업은행 434-115361-01-016 (이상용) / 010-6369-8443 / momo8443@daum.net · KIMPO: 농협 351-1383-7634-13 (모모유통) / 010-5789-9431 / momokimpo@nate.com - getSupplierByBranch(branch) helper 거래명세표 supplier 분기 (3개 API): - /api/m/orders/detail: order.STATEMENT_BRANCH 따라 supplier 객체 결정 - /api/m/orders/statement/[id]: xlsx 다운로드도 동일 - /api/m/orders/approve: 메일 발송 stmt 도 동일 사용자 수정 폼: - /api/admin/users/detail: statement_branch 반환 (default 'HQ') - /api/admin/users/save: statement_branch 받아 UPDATE - /admin-panel/user-form: "기준 거래명세서" select 추가 (본사/김포) 흐름: 거래처 사용자의 기준을 김포로 설정 → 그 사용자의 발주에 대한 거래명세표 supplier 가 김포 정보로 표시 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
-- 사용자별 거래명세서 기준 지점 (본사 / 김포)
|
||||
-- 거래명세표 발급 시 공급자(supplier) 정보를 두 가지로 분기하기 위함
|
||||
ALTER TABLE user_info
|
||||
ADD COLUMN IF NOT EXISTS statement_branch VARCHAR(10) DEFAULT 'HQ';
|
||||
|
||||
-- 기존 사용자는 모두 본사로 default
|
||||
UPDATE user_info SET statement_branch = 'HQ' WHERE statement_branch IS NULL;
|
||||
@@ -111,6 +111,17 @@ function UserForm() {
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-[11px] font-medium text-gray-500 mb-0.5">기준 거래명세서 <span className="text-gray-400 font-normal">(공급자 정보)</span></label>
|
||||
<select
|
||||
value={form.statement_branch || "HQ"}
|
||||
onChange={(e) => set("statement_branch", e.target.value)}
|
||||
className="h-8 w-full rounded border border-gray-300 bg-white px-2 text-[12px]"
|
||||
>
|
||||
<option value="HQ">본사 (기업은행 / 이상용)</option>
|
||||
<option value="KIMPO">김포 (농협 / 모모유통)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-[11px] font-medium text-gray-500 mb-0.5">특수 권한</label>
|
||||
<div className="flex gap-2 h-8 items-center">
|
||||
|
||||
@@ -17,6 +17,7 @@ export async function POST(request: NextRequest) {
|
||||
COALESCE(unlimited_qty, 'N') AS "unlimited_qty",
|
||||
COALESCE(view_hidden, 'N') AS "view_hidden",
|
||||
default_wh_objid::text AS "default_wh_objid",
|
||||
COALESCE(statement_branch, 'HQ') AS "statement_branch",
|
||||
TO_CHAR(regdate, 'YYYY-MM-DD') AS "regdate"
|
||||
FROM user_info WHERE user_id = $1`,
|
||||
[body.userId || ""]
|
||||
|
||||
@@ -33,6 +33,7 @@ export async function POST(request: NextRequest) {
|
||||
const viewHidden = body.view_hidden === "Y" ? "Y" : "N";
|
||||
// 빈 문자열 / undefined → NULL 처리
|
||||
const defaultWh = body.default_wh_objid && String(body.default_wh_objid).trim() !== "" ? body.default_wh_objid : null;
|
||||
const stmtBranch = body.statement_branch === "KIMPO" ? "KIMPO" : "HQ";
|
||||
await client.query(
|
||||
`UPDATE user_info SET
|
||||
user_name=$1, sabun=$2, dept_code=$3, dept_name=$4,
|
||||
@@ -40,14 +41,15 @@ export async function POST(request: NextRequest) {
|
||||
address=COALESCE($11, address), ceo_name=COALESCE($12, ceo_name),
|
||||
biz_no=COALESCE($13, biz_no),
|
||||
unlimited_qty=$14, view_hidden=$15,
|
||||
default_wh_objid=$16
|
||||
default_wh_objid=$16,
|
||||
statement_branch=$17
|
||||
WHERE user_id=$10`,
|
||||
[body.user_name || "", body.sabun || "", body.dept_code || "",
|
||||
body.dept_name || "", body.position_name || "", body.email || "",
|
||||
body.cell_phone || "", body.user_type || "", body.tel || "",
|
||||
body.user_id || "",
|
||||
body.address ?? null, body.ceo_name ?? null, body.biz_no ?? null,
|
||||
unlimited, viewHidden, defaultWh]
|
||||
unlimited, viewHidden, defaultWh, stmtBranch]
|
||||
);
|
||||
}
|
||||
return NextResponse.json({ success: true, message: isNew ? "등록되었습니다." : "수정되었습니다." });
|
||||
|
||||
@@ -5,6 +5,7 @@ import { createObjectId } from "@/lib/utils";
|
||||
import { requireMomoAdmin } from "@/lib/momo-guard";
|
||||
import { buildStatementHtml, buildStatementXlsx } from "@/lib/excel-statement";
|
||||
import { sendMail } from "@/lib/mailer";
|
||||
import { getSupplierByBranch } from "@/lib/momo-branches";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const g = await requireMomoAdmin();
|
||||
@@ -114,6 +115,7 @@ export async function POST(req: NextRequest) {
|
||||
`SELECT O.objid, O.order_no, TO_CHAR(O.order_date,'YYYY-MM-DD') AS order_date,
|
||||
U.user_name AS company_name, U.email,
|
||||
U.ceo_name, U.biz_no, U.cell_phone AS phone, U.address,
|
||||
U.statement_branch,
|
||||
O.total_supply, O.total_vat, O.total_amount,
|
||||
O.total_taxfree, O.total_taxable
|
||||
FROM momo_orders O
|
||||
@@ -137,12 +139,10 @@ export async function POST(req: NextRequest) {
|
||||
bizNo: order.biz_no as string | undefined,
|
||||
phone: order.phone as string | undefined,
|
||||
},
|
||||
supplier: {
|
||||
companyName: "모모유통",
|
||||
bankAccount: process.env.MOMO_BANK_ACCOUNT ?? "기업은행 ____",
|
||||
phone: process.env.MOMO_PHONE ?? "010-6624-5315",
|
||||
email: process.env.SMTP_FROM ?? "momo8443@daum.net",
|
||||
},
|
||||
supplier: (() => {
|
||||
const b = getSupplierByBranch(order.statement_branch as string | undefined);
|
||||
return { companyName: b.NAME, bankAccount: b.BANK_ACCOUNT, phone: b.PHONE, email: b.EMAIL };
|
||||
})(),
|
||||
items: items.map((it) => ({
|
||||
seq: Number(it.seq),
|
||||
itemName: String(it.item_name_snap),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { queryOne, queryRows } from "@/lib/db";
|
||||
import { requireMomoUser } from "@/lib/momo-guard";
|
||||
import { getSupplierByBranch } from "@/lib/momo-branches";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const r = await requireMomoUser();
|
||||
@@ -17,6 +18,7 @@ export async function POST(req: NextRequest) {
|
||||
U.user_name AS "COMPANY_NAME", U.email AS "EMAIL",
|
||||
U.ceo_name AS "CEO_NAME", U.biz_no AS "BIZ_NO",
|
||||
U.cell_phone AS "PHONE", U.address AS "ADDRESS",
|
||||
U.statement_branch AS "STATEMENT_BRANCH",
|
||||
O.status AS "STATUS", O.memo AS "MEMO",
|
||||
O.total_supply AS "TOTAL_SUPPLY", O.total_vat AS "TOTAL_VAT",
|
||||
O.total_amount AS "TOTAL_AMOUNT",
|
||||
@@ -75,16 +77,9 @@ export async function POST(req: NextRequest) {
|
||||
[objid]
|
||||
);
|
||||
|
||||
// 공급자(모모유통) 정보 — 환경변수 또는 기본값
|
||||
const supplier = {
|
||||
NAME: process.env.MOMO_COMPANY_NAME || "모모유통",
|
||||
CEO: process.env.MOMO_COMPANY_CEO || "이상용",
|
||||
BIZ_NO: process.env.MOMO_COMPANY_BIZNO || "",
|
||||
BANK_ACCOUNT: process.env.MOMO_BANK_ACCOUNT || "기업은행 434-115361-01-016 (이상용)",
|
||||
PHONE: process.env.MOMO_PHONE || "010-6369-8443",
|
||||
EMAIL: process.env.MOMO_EMAIL || "momo8443@daum.net",
|
||||
ADDRESS: process.env.MOMO_COMPANY_ADDR || "",
|
||||
};
|
||||
// 공급자(모모유통) 정보 — 거래처(사용자)의 statement_branch (HQ / KIMPO) 에 따라 분기
|
||||
const branch = (order as { STATEMENT_BRANCH?: string }).STATEMENT_BRANCH ?? "HQ";
|
||||
const supplier = getSupplierByBranch(branch);
|
||||
|
||||
return NextResponse.json({ success: true, order, items, supplier });
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { NextRequest, NextResponse } from "next/server";
|
||||
import { queryOne, queryRows } from "@/lib/db";
|
||||
import { requireMomoUser } from "@/lib/momo-guard";
|
||||
import { buildStatementXlsx } from "@/lib/excel-statement";
|
||||
import { getSupplierByBranch } from "@/lib/momo-branches";
|
||||
|
||||
export async function GET(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
|
||||
const r = await requireMomoUser();
|
||||
@@ -18,6 +19,7 @@ export async function GET(req: NextRequest, ctx: { params: Promise<{ id: string
|
||||
U.cell_phone AS phone,
|
||||
U.address AS address,
|
||||
U.email AS email,
|
||||
U.statement_branch AS statement_branch,
|
||||
O.total_supply, O.total_vat, O.total_amount,
|
||||
O.total_taxfree, O.total_taxable,
|
||||
COALESCE(O.paid_amount, 0) AS paid_amount
|
||||
@@ -55,12 +57,10 @@ export async function GET(req: NextRequest, ctx: { params: Promise<{ id: string
|
||||
bizNo: order.biz_no as string | undefined,
|
||||
phone: order.phone as string | undefined,
|
||||
},
|
||||
supplier: {
|
||||
companyName: "모모유통",
|
||||
bankAccount: process.env.MOMO_BANK_ACCOUNT ?? "기업은행 ____",
|
||||
phone: process.env.MOMO_PHONE ?? "010-6624-5315",
|
||||
email: process.env.SMTP_FROM ?? "momo8443@daum.net",
|
||||
},
|
||||
supplier: (() => {
|
||||
const b = getSupplierByBranch(order.statement_branch as string | undefined);
|
||||
return { companyName: b.NAME, bankAccount: b.BANK_ACCOUNT, phone: b.PHONE, email: b.EMAIL };
|
||||
})(),
|
||||
items: items.map((it, idx) => {
|
||||
const isExtra = it.kind === "DELIVERY" || it.kind === "CHARTER";
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// 모모유통 공급자(supplier) 정보 — 거래명세표/계산서 발행 시 사용자별로 분기
|
||||
// 사용자(user_info.statement_branch) 가 'HQ' / 'KIMPO' 중 어느 값이냐에 따라 적용
|
||||
export type StatementBranch = "HQ" | "KIMPO";
|
||||
|
||||
export interface BranchSupplier {
|
||||
NAME: string;
|
||||
CEO: string;
|
||||
BANK_ACCOUNT: string;
|
||||
PHONE: string;
|
||||
EMAIL: string;
|
||||
BIZ_NO: string;
|
||||
ADDRESS: string;
|
||||
}
|
||||
|
||||
export const SUPPLIER_BRANCHES: Record<StatementBranch, BranchSupplier> = {
|
||||
HQ: {
|
||||
NAME: "모모유통",
|
||||
CEO: "이상용",
|
||||
BANK_ACCOUNT: "기업은행 434-115361-01-016 (이상용)",
|
||||
PHONE: "010-6369-8443",
|
||||
EMAIL: "momo8443@daum.net",
|
||||
BIZ_NO: "",
|
||||
ADDRESS: "",
|
||||
},
|
||||
KIMPO: {
|
||||
NAME: "모모유통",
|
||||
CEO: "이상용",
|
||||
BANK_ACCOUNT: "농협 351-1383-7634-13 (모모유통)",
|
||||
PHONE: "010-5789-9431",
|
||||
EMAIL: "momokimpo@nate.com",
|
||||
BIZ_NO: "",
|
||||
ADDRESS: "",
|
||||
},
|
||||
};
|
||||
|
||||
export function getSupplierByBranch(branch?: string | null): BranchSupplier {
|
||||
const key = (branch === "KIMPO" ? "KIMPO" : "HQ") as StatementBranch;
|
||||
return SUPPLIER_BRANCHES[key];
|
||||
}
|
||||
Reference in New Issue
Block a user