feat: 제품 검색에 분류 뱃지 + 도매상 재고 추가 (PostgreSQL 방어적 lazy fetch)
This commit is contained in:
parent
4c93ee038a
commit
6a786ff042
@ -3125,6 +3125,23 @@ def api_products():
|
||||
if animal_only and not is_animal:
|
||||
continue
|
||||
|
||||
# APC 조회 (동물약인 경우)
|
||||
apc = None
|
||||
if is_animal:
|
||||
try:
|
||||
apc_result = drug_session.execute(text("""
|
||||
SELECT TOP 1 CD_CD_BARCODE
|
||||
FROM CD_ITEM_UNIT_MEMBER
|
||||
WHERE DRUGCODE = :drug_code AND CD_CD_BARCODE LIKE '023%'
|
||||
"""), {'drug_code': row.drug_code})
|
||||
apc_row = apc_result.fetchone()
|
||||
if apc_row:
|
||||
apc = apc_row[0]
|
||||
elif row.barcode:
|
||||
apc = row.barcode # 바코드=APC 케이스
|
||||
except:
|
||||
pass
|
||||
|
||||
items.append({
|
||||
'drug_code': row.drug_code or '',
|
||||
'product_name': row.product_name or '',
|
||||
@ -3134,9 +3151,44 @@ def api_products():
|
||||
'supplier': row.supplier or '',
|
||||
'is_set': bool(row.is_set),
|
||||
'is_animal_drug': is_animal,
|
||||
'stock': int(row.stock) if row.stock else 0
|
||||
'stock': int(row.stock) if row.stock else 0,
|
||||
'apc': apc,
|
||||
'category': None, # PostgreSQL에서 lazy fetch
|
||||
'wholesaler_stock': None
|
||||
})
|
||||
|
||||
# 동물약 분류 Lazy Fetch (PostgreSQL) - 실패해도 무시
|
||||
animal_items = [i for i in items if i['is_animal_drug'] and i['apc']]
|
||||
if animal_items:
|
||||
try:
|
||||
from sqlalchemy import create_engine
|
||||
pg_engine = create_engine('postgresql://admin:trajet6640@192.168.0.87:5432/apdb_master',
|
||||
connect_args={'connect_timeout': 3}) # 3초 타임아웃
|
||||
with pg_engine.connect() as conn:
|
||||
apc_list = [i['apc'] for i in animal_items if i['apc']]
|
||||
if apc_list:
|
||||
placeholders = ','.join([f"'{a}'" for a in apc_list])
|
||||
# 분류 + 도매상 재고 조회
|
||||
result = conn.execute(text(f"""
|
||||
SELECT
|
||||
A.apc,
|
||||
A.llm_pharm->>'분류' as category,
|
||||
COALESCE(SUM(I.quantity), 0) as wholesaler_stock
|
||||
FROM apc A
|
||||
LEFT JOIN inventory I ON I.apdb_id = A.idx
|
||||
WHERE A.apc IN ({placeholders})
|
||||
GROUP BY A.apc, A.llm_pharm
|
||||
"""))
|
||||
pg_map = {row.apc: {'category': row.category, 'ws': int(row.wholesaler_stock)} for row in result}
|
||||
|
||||
for item in items:
|
||||
if item['apc'] and item['apc'] in pg_map:
|
||||
item['category'] = pg_map[item['apc']]['category']
|
||||
item['wholesaler_stock'] = pg_map[item['apc']]['ws']
|
||||
except Exception as pg_err:
|
||||
logging.warning(f"PostgreSQL 분류 조회 실패 (무시): {pg_err}")
|
||||
# PostgreSQL 실패해도 MSSQL 데이터는 정상 반환
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'items': items,
|
||||
|
||||
@ -725,12 +725,23 @@
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = productsData.map((item, idx) => `
|
||||
tbody.innerHTML = productsData.map((item, idx) => {
|
||||
// 분류 뱃지 (동물약만)
|
||||
const categoryBadge = item.category
|
||||
? `<span style="display:inline-block;background:#8b5cf6;color:#fff;font-size:10px;padding:2px 5px;border-radius:3px;margin-left:4px;">${escapeHtml(item.category)}</span>`
|
||||
: '';
|
||||
// 도매상 재고 표시 (동물약만)
|
||||
const wsStock = (item.wholesaler_stock && item.wholesaler_stock > 0)
|
||||
? `<span style="color:#3b82f6;font-size:11px;margin-left:4px;">(도매 ${item.wholesaler_stock})</span>`
|
||||
: '';
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td>
|
||||
<div class="product-name">
|
||||
${escapeHtml(item.product_name)}
|
||||
${item.is_animal_drug ? '<span style="display:inline-block;background:#10b981;color:#fff;font-size:11px;padding:2px 6px;border-radius:4px;margin-left:6px;">🐾 동물약</span>' : ''}
|
||||
${categoryBadge}
|
||||
</div>
|
||||
<div class="product-supplier ${item.is_set ? 'set' : ''}">${escapeHtml(item.supplier) || ''}</div>
|
||||
</td>
|
||||
@ -738,13 +749,13 @@
|
||||
<td>${item.barcode
|
||||
? `<span class="code code-barcode">${item.barcode}</span>`
|
||||
: `<span class="code code-na">없음</span>`}</td>
|
||||
<td class="stock ${(item.stock || 0) > 0 ? 'in-stock' : 'out-stock'}">${item.stock || 0}</td>
|
||||
<td class="stock ${(item.stock || 0) > 0 ? 'in-stock' : 'out-stock'}">${item.stock || 0}${wsStock}</td>
|
||||
<td class="price">${formatPrice(item.sale_price)}</td>
|
||||
<td>
|
||||
<button class="btn-qr" onclick="printQR(${idx})">🏷️ QR</button>
|
||||
</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
`}).join('');
|
||||
}
|
||||
|
||||
// ── QR 인쇄 관련 ──
|
||||
|
||||
Loading…
Reference in New Issue
Block a user