회사 관리 - 등록 페이지 수정
This commit is contained in:
@@ -8,6 +8,7 @@ import config from "../config/environment";
|
||||
import { AdminService } from "../services/adminService";
|
||||
import { EncryptUtil } from "../utils/encryptUtil";
|
||||
import { FileSystemManager } from "../utils/fileSystemManager";
|
||||
import { validateBusinessNumber } from "../utils/businessNumberValidator";
|
||||
|
||||
/**
|
||||
* 관리자 메뉴 목록 조회
|
||||
@@ -609,9 +610,15 @@ export const getCompanyList = async (
|
||||
|
||||
// Raw Query로 회사 목록 조회
|
||||
const companies = await query<any>(
|
||||
`SELECT
|
||||
company_code,
|
||||
` SELECT
|
||||
company_code,
|
||||
company_name,
|
||||
business_registration_number,
|
||||
representative_name,
|
||||
representative_phone,
|
||||
email,
|
||||
website,
|
||||
address,
|
||||
status,
|
||||
writer,
|
||||
regdate
|
||||
@@ -1659,9 +1666,15 @@ export async function getCompanyListFromDB(
|
||||
|
||||
// Raw Query로 회사 목록 조회
|
||||
const companies = await query<any>(
|
||||
`SELECT
|
||||
company_code,
|
||||
` SELECT
|
||||
company_code,
|
||||
company_name,
|
||||
business_registration_number,
|
||||
representative_name,
|
||||
representative_phone,
|
||||
email,
|
||||
website,
|
||||
address,
|
||||
writer,
|
||||
regdate,
|
||||
status
|
||||
@@ -2440,6 +2453,25 @@ export const createCompany = async (
|
||||
[company_name.trim()]
|
||||
);
|
||||
|
||||
// 사업자등록번호 유효성 검증
|
||||
const businessNumberValidation = validateBusinessNumber(
|
||||
req.body.business_registration_number?.trim() || ""
|
||||
);
|
||||
if (!businessNumberValidation.isValid) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: businessNumberValidation.message,
|
||||
errorCode: "INVALID_BUSINESS_NUMBER",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Raw Query로 사업자등록번호 중복 체크
|
||||
const existingBusinessNumber = await queryOne<any>(
|
||||
`SELECT company_code FROM company_mng WHERE business_registration_number = $1`,
|
||||
[req.body.business_registration_number?.trim()]
|
||||
);
|
||||
|
||||
if (existingCompany) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
@@ -2449,6 +2481,15 @@ export const createCompany = async (
|
||||
return;
|
||||
}
|
||||
|
||||
if (existingBusinessNumber) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: "이미 등록된 사업자등록번호입니다.",
|
||||
errorCode: "DUPLICATE_BUSINESS_NUMBER",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// PostgreSQL 클라이언트 생성 (복잡한 코드 생성 쿼리용)
|
||||
const client = new Client({
|
||||
connectionString:
|
||||
@@ -2474,11 +2515,17 @@ export const createCompany = async (
|
||||
const insertQuery = `
|
||||
INSERT INTO company_mng (
|
||||
company_code,
|
||||
company_name,
|
||||
company_name,
|
||||
business_registration_number,
|
||||
representative_name,
|
||||
representative_phone,
|
||||
email,
|
||||
website,
|
||||
address,
|
||||
writer,
|
||||
regdate,
|
||||
status
|
||||
) VALUES ($1, $2, $3, $4, $5)
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
RETURNING *
|
||||
`;
|
||||
|
||||
@@ -2488,6 +2535,12 @@ export const createCompany = async (
|
||||
const insertValues = [
|
||||
companyCode,
|
||||
company_name.trim(),
|
||||
req.body.business_registration_number?.trim() || null,
|
||||
req.body.representative_name?.trim() || null,
|
||||
req.body.representative_phone?.trim() || null,
|
||||
req.body.email?.trim() || null,
|
||||
req.body.website?.trim() || null,
|
||||
req.body.address?.trim() || null,
|
||||
writer,
|
||||
new Date(),
|
||||
"active",
|
||||
@@ -2552,7 +2605,16 @@ export const updateCompany = async (
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const { companyCode } = req.params;
|
||||
const { company_name, status } = req.body;
|
||||
const {
|
||||
company_name,
|
||||
business_registration_number,
|
||||
representative_name,
|
||||
representative_phone,
|
||||
email,
|
||||
website,
|
||||
address,
|
||||
status,
|
||||
} = req.body;
|
||||
|
||||
logger.info("회사 정보 수정 요청", {
|
||||
companyCode,
|
||||
@@ -2586,13 +2648,61 @@ export const updateCompany = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// 사업자등록번호 중복 체크 및 유효성 검증 (자기 자신 제외)
|
||||
if (business_registration_number && business_registration_number.trim()) {
|
||||
// 유효성 검증
|
||||
const businessNumberValidation = validateBusinessNumber(business_registration_number.trim());
|
||||
if (!businessNumberValidation.isValid) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: businessNumberValidation.message,
|
||||
errorCode: "INVALID_BUSINESS_NUMBER",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 중복 체크
|
||||
const duplicateBusinessNumber = await queryOne<any>(
|
||||
`SELECT company_code FROM company_mng
|
||||
WHERE business_registration_number = $1 AND company_code != $2`,
|
||||
[business_registration_number.trim(), companyCode]
|
||||
);
|
||||
|
||||
if (duplicateBusinessNumber) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
message: "이미 등록된 사업자등록번호입니다.",
|
||||
errorCode: "DUPLICATE_BUSINESS_NUMBER",
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Raw Query로 회사 정보 수정
|
||||
const result = await query<any>(
|
||||
`UPDATE company_mng
|
||||
SET company_name = $1, status = $2
|
||||
WHERE company_code = $3
|
||||
SET
|
||||
company_name = $1,
|
||||
business_registration_number = $2,
|
||||
representative_name = $3,
|
||||
representative_phone = $4,
|
||||
email = $5,
|
||||
website = $6,
|
||||
address = $7,
|
||||
status = $8
|
||||
WHERE company_code = $9
|
||||
RETURNING *`,
|
||||
[company_name.trim(), status || "active", companyCode]
|
||||
[
|
||||
company_name.trim(),
|
||||
business_registration_number?.trim() || null,
|
||||
representative_name?.trim() || null,
|
||||
representative_phone?.trim() || null,
|
||||
email?.trim() || null,
|
||||
website?.trim() || null,
|
||||
address?.trim() || null,
|
||||
status || "active",
|
||||
companyCode,
|
||||
]
|
||||
);
|
||||
|
||||
if (result.length === 0) {
|
||||
|
||||
52
backend-node/src/utils/businessNumberValidator.ts
Normal file
52
backend-node/src/utils/businessNumberValidator.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 사업자등록번호 유효성 검사 유틸리티 (백엔드)
|
||||
*/
|
||||
|
||||
/**
|
||||
* 사업자등록번호 포맷 검증
|
||||
*/
|
||||
export function validateBusinessNumberFormat(value: string): boolean {
|
||||
if (!value || value.trim() === "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 하이픈 제거
|
||||
const cleaned = value.replace(/-/g, "");
|
||||
|
||||
// 숫자 10자리인지 확인
|
||||
if (!/^\d{10}$/.test(cleaned)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 사업자등록번호 종합 검증 (포맷만 검사)
|
||||
* 실제 국세청 검증은 API 호출로 처리하는 것을 권장
|
||||
*/
|
||||
export function validateBusinessNumber(value: string): {
|
||||
isValid: boolean;
|
||||
message: string;
|
||||
} {
|
||||
if (!value || value.trim() === "") {
|
||||
return {
|
||||
isValid: false,
|
||||
message: "사업자등록번호를 입력해주세요.",
|
||||
};
|
||||
}
|
||||
|
||||
if (!validateBusinessNumberFormat(value)) {
|
||||
return {
|
||||
isValid: false,
|
||||
message: "사업자등록번호는 10자리 숫자여야 합니다.",
|
||||
};
|
||||
}
|
||||
|
||||
// 포맷만 검증하고 통과
|
||||
return {
|
||||
isValid: true,
|
||||
message: "",
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user