feat: 동물약만 체크 시 검색어 없이 전체 조회 가능
- 동물약은 39건뿐이라 전체 조회해도 빠름 - 동물약만 체크 + 검색어 없음 → 전체 동물약 리스트 - 쿼리 조건 동적 생성 (animal_condition, search_condition)
This commit is contained in:
parent
a0cbb984e5
commit
2859dc43cc
123
backend/app.py
123
backend/app.py
@ -3313,15 +3313,26 @@ def api_products():
|
|||||||
animal_only = request.args.get('animal_only', '0') == '1'
|
animal_only = request.args.get('animal_only', '0') == '1'
|
||||||
in_stock_only = request.args.get('in_stock_only', '0') == '1'
|
in_stock_only = request.args.get('in_stock_only', '0') == '1'
|
||||||
|
|
||||||
if not search or len(search) < 2:
|
# 동물약만 체크시 검색어 없어도 전체 조회 가능
|
||||||
|
if not animal_only and (not search or len(search) < 2):
|
||||||
return jsonify({'success': False, 'error': '검색어는 2글자 이상 입력하세요'})
|
return jsonify({'success': False, 'error': '검색어는 2글자 이상 입력하세요'})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
drug_session = db_manager.get_session('PM_DRUG')
|
drug_session = db_manager.get_session('PM_DRUG')
|
||||||
|
|
||||||
|
# WHERE 조건 생성 (동물약 전체 조회 시 검색 조건 없음)
|
||||||
|
search_condition = ""
|
||||||
|
if search:
|
||||||
|
search_condition = """
|
||||||
|
AND (G.GoodsName LIKE :search_like
|
||||||
|
OR G.DrugCode LIKE :search_like
|
||||||
|
OR G.BARCODE LIKE :search_like)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 동물약만 필터 (쿼리에서 직접 처리)
|
||||||
|
animal_condition = "AND G.POS_BOON = '010103'" if animal_only else ""
|
||||||
|
|
||||||
# 제품 검색 쿼리 - 사용약품만 옵션에 따라 JOIN 방식 변경
|
# 제품 검색 쿼리 - 사용약품만 옵션에 따라 JOIN 방식 변경
|
||||||
# in_stock_only: INNER JOIN으로 재고 있는 제품만 (빠름)
|
|
||||||
# 그렇지 않으면: LEFT JOIN으로 모든 제품 (느림)
|
|
||||||
if in_stock_only:
|
if in_stock_only:
|
||||||
# 최적화된 쿼리: 재고 있는 제품만 (IM_total INNER JOIN)
|
# 최적화된 쿼리: 재고 있는 제품만 (IM_total INNER JOIN)
|
||||||
products_query = text(f"""
|
products_query = text(f"""
|
||||||
@ -3337,62 +3348,76 @@ def api_products():
|
|||||||
IT.IM_QT_sale_debit as stock
|
IT.IM_QT_sale_debit as stock
|
||||||
FROM CD_GOODS G
|
FROM CD_GOODS G
|
||||||
INNER JOIN IM_total IT ON G.DrugCode = IT.DrugCode AND IT.IM_QT_sale_debit > 0
|
INNER JOIN IM_total IT ON G.DrugCode = IT.DrugCode AND IT.IM_QT_sale_debit > 0
|
||||||
WHERE
|
WHERE 1=1
|
||||||
G.GoodsName LIKE :search_like
|
{animal_condition}
|
||||||
OR G.DrugCode LIKE :search_like
|
{search_condition}
|
||||||
OR G.BARCODE LIKE :search_like
|
|
||||||
ORDER BY G.GoodsName
|
ORDER BY G.GoodsName
|
||||||
""")
|
""")
|
||||||
else:
|
else:
|
||||||
# 전체 쿼리 (OUTER APPLY 포함, 느림)
|
# 전체 쿼리 (OUTER APPLY 포함, 느림)
|
||||||
products_query = text(f"""
|
# 동물약만 조회 시 OUTER APPLY 생략 가능
|
||||||
SELECT TOP {limit}
|
if animal_only:
|
||||||
G.DrugCode as drug_code,
|
products_query = text(f"""
|
||||||
G.GoodsName as product_name,
|
SELECT TOP {limit}
|
||||||
COALESCE(NULLIF(G.BARCODE, ''), U.CD_CD_BARCODE, '') as barcode,
|
G.DrugCode as drug_code,
|
||||||
G.Saleprice as sale_price,
|
G.GoodsName as product_name,
|
||||||
G.Price as cost_price,
|
COALESCE(NULLIF(G.BARCODE, ''), '') as barcode,
|
||||||
CASE
|
G.Saleprice as sale_price,
|
||||||
WHEN G.SplName IS NOT NULL AND G.SplName != '' THEN G.SplName
|
G.Price as cost_price,
|
||||||
WHEN SET_CHK.is_set = 1 THEN N'세트상품'
|
ISNULL(G.SplName, '') as supplier,
|
||||||
ELSE ''
|
0 as is_set,
|
||||||
END as supplier,
|
G.POS_BOON as pos_boon,
|
||||||
CASE WHEN SET_CHK.is_set = 1 THEN 1 ELSE 0 END as is_set,
|
ISNULL(IT.IM_QT_sale_debit, 0) as stock
|
||||||
G.POS_BOON as pos_boon,
|
FROM CD_GOODS G
|
||||||
ISNULL(IT.IM_QT_sale_debit, 0) as stock
|
LEFT JOIN IM_total IT ON G.DrugCode = IT.DrugCode
|
||||||
FROM CD_GOODS G
|
WHERE G.POS_BOON = '010103'
|
||||||
LEFT JOIN IM_total IT ON G.DrugCode = IT.DrugCode
|
{search_condition}
|
||||||
OUTER APPLY (
|
ORDER BY G.GoodsName
|
||||||
SELECT TOP 1 CD_CD_BARCODE
|
""")
|
||||||
FROM CD_ITEM_UNIT_MEMBER
|
else:
|
||||||
WHERE DRUGCODE = G.DrugCode AND CD_CD_BARCODE IS NOT NULL AND CD_CD_BARCODE != ''
|
products_query = text(f"""
|
||||||
) U
|
SELECT TOP {limit}
|
||||||
OUTER APPLY (
|
G.DrugCode as drug_code,
|
||||||
SELECT TOP 1 1 as is_set
|
G.GoodsName as product_name,
|
||||||
FROM CD_item_set
|
COALESCE(NULLIF(G.BARCODE, ''), U.CD_CD_BARCODE, '') as barcode,
|
||||||
WHERE SetCode = G.DrugCode AND DrugCode = 'SET0000'
|
G.Saleprice as sale_price,
|
||||||
) SET_CHK
|
G.Price as cost_price,
|
||||||
WHERE
|
CASE
|
||||||
G.GoodsName LIKE :search_like
|
WHEN G.SplName IS NOT NULL AND G.SplName != '' THEN G.SplName
|
||||||
OR G.DrugCode LIKE :search_like
|
WHEN SET_CHK.is_set = 1 THEN N'세트상품'
|
||||||
OR G.BARCODE LIKE :search_like
|
ELSE ''
|
||||||
OR U.CD_CD_BARCODE LIKE :search_like
|
END as supplier,
|
||||||
ORDER BY G.GoodsName
|
CASE WHEN SET_CHK.is_set = 1 THEN 1 ELSE 0 END as is_set,
|
||||||
""")
|
G.POS_BOON as pos_boon,
|
||||||
|
ISNULL(IT.IM_QT_sale_debit, 0) as stock
|
||||||
|
FROM CD_GOODS G
|
||||||
|
LEFT JOIN IM_total IT ON G.DrugCode = IT.DrugCode
|
||||||
|
OUTER APPLY (
|
||||||
|
SELECT TOP 1 CD_CD_BARCODE
|
||||||
|
FROM CD_ITEM_UNIT_MEMBER
|
||||||
|
WHERE DRUGCODE = G.DrugCode AND CD_CD_BARCODE IS NOT NULL AND CD_CD_BARCODE != ''
|
||||||
|
) U
|
||||||
|
OUTER APPLY (
|
||||||
|
SELECT TOP 1 1 as is_set
|
||||||
|
FROM CD_item_set
|
||||||
|
WHERE SetCode = G.DrugCode AND DrugCode = 'SET0000'
|
||||||
|
) SET_CHK
|
||||||
|
WHERE 1=1
|
||||||
|
{search_condition}
|
||||||
|
ORDER BY G.GoodsName
|
||||||
|
""")
|
||||||
|
|
||||||
search_like = f'%{search}%'
|
# 파라미터 설정 (검색어가 있을 때만)
|
||||||
rows = drug_session.execute(products_query, {
|
params = {}
|
||||||
'search_like': search_like
|
if search:
|
||||||
}).fetchall()
|
params['search_like'] = f'%{search}%'
|
||||||
|
|
||||||
|
rows = drug_session.execute(products_query, params).fetchall()
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
for row in rows:
|
for row in rows:
|
||||||
is_animal = row.pos_boon == '010103'
|
is_animal = row.pos_boon == '010103'
|
||||||
|
|
||||||
# 동물약만 필터링
|
|
||||||
if animal_only and not is_animal:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# APC 조회 (동물약인 경우)
|
# APC 조회 (동물약인 경우)
|
||||||
apc = None
|
apc = None
|
||||||
if is_animal:
|
if is_animal:
|
||||||
|
|||||||
@ -695,19 +695,23 @@
|
|||||||
|
|
||||||
function searchProducts() {
|
function searchProducts() {
|
||||||
const search = document.getElementById('searchInput').value.trim();
|
const search = document.getElementById('searchInput').value.trim();
|
||||||
if (!search) {
|
const animalOnly = document.getElementById('animalOnly').checked;
|
||||||
alert('검색어를 입력하세요');
|
|
||||||
return;
|
// 동물약만 체크시 검색어 없어도 전체 조회 가능
|
||||||
}
|
if (!animalOnly) {
|
||||||
if (search.length < 2) {
|
if (!search) {
|
||||||
alert('2글자 이상 입력하세요');
|
alert('검색어를 입력하세요');
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if (search.length < 2) {
|
||||||
|
alert('2글자 이상 입력하세요');
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tbody = document.getElementById('productsTableBody');
|
const tbody = document.getElementById('productsTableBody');
|
||||||
tbody.innerHTML = '<tr><td colspan="6" class="empty-state"><p>검색 중...</p></td></tr>';
|
tbody.innerHTML = '<tr><td colspan="6" class="empty-state"><p>검색 중...</p></td></tr>';
|
||||||
|
|
||||||
const animalOnly = document.getElementById('animalOnly').checked;
|
|
||||||
const inStockOnly = document.getElementById('inStockOnly').checked;
|
const inStockOnly = document.getElementById('inStockOnly').checked;
|
||||||
let url = `/api/products?search=${encodeURIComponent(search)}`;
|
let url = `/api/products?search=${encodeURIComponent(search)}`;
|
||||||
if (animalOnly) url += '&animal_only=1';
|
if (animalOnly) url += '&animal_only=1';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user