1245 lines
55 KiB
Python
1245 lines
55 KiB
Python
import sys
|
|
import configparser
|
|
import os
|
|
import pandas as pd
|
|
import logging
|
|
from PyQt5.QtCore import Qt
|
|
from PyQt5 import QtWidgets, QtCore
|
|
from PyQt5.QtGui import QFont
|
|
import re, json
|
|
from src.toggleSwitch import ToggleSwitch # toggleSwitch.py 파일에서 ToggleSwitch 클래스를 임포트
|
|
from src.logger_module import setup_logger
|
|
import ctypes
|
|
from src.kipris_settingUI import SettingsDialog
|
|
from src.kipris_api_from_publicdata import Kipris_API
|
|
# from src.kipris_web_from_playwright import Kipris_WEB
|
|
from src.kiprisThread import *
|
|
# from src.search_display import TrademarkSearchDisplay
|
|
from src.result_widget import ResultWidget
|
|
from src.currencyInfo import ExchangeRateScraper
|
|
|
|
def minimize_console():
|
|
""" 콘솔 창을 최소화하는 함수 """
|
|
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
|
|
if hwnd != 0:
|
|
ctypes.windll.user32.ShowWindow(hwnd, 6) # SW_MINIMIZE
|
|
|
|
|
|
class DeliveryFeeCalculator(QtWidgets.QWidget):
|
|
def __init__(self, logger):
|
|
super().__init__()
|
|
self.logger = logger
|
|
# self.config = configparser.ConfigParser()
|
|
self.config_path = 'config.ini'
|
|
|
|
self.use_kipris = False
|
|
self.usage_mode = "web"
|
|
self.api_key = ""
|
|
self.kiprisAPI = None
|
|
self.searchThread = None # 스레드 객체를 저장할 멤버 변수 추가
|
|
self.asyncWorker = None
|
|
self.search_keyword = None
|
|
self.set_status =[]
|
|
self.web_scraper = None # 웹방식 Playwright 객체 미리 초기화
|
|
self.currentURL = ""
|
|
self.config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json')
|
|
|
|
self.maxWeightSet = 25
|
|
self.maxLengthSet = 100
|
|
self.maxVolumeSet = 160
|
|
self.currentMaxLength = 1
|
|
self.roundVolume = 1
|
|
self.currentWeight = 1
|
|
self.currentVolume = 1
|
|
self.fontSize = 14
|
|
self.weightInterval = 0.5
|
|
self.setSaveSetting = True
|
|
|
|
self.addFee = 1000
|
|
self.addFeeSetting = 20
|
|
self.addFeeInterval = 5
|
|
|
|
self.setUSD = None
|
|
self.setCNY = None
|
|
self.currentCurrency = None
|
|
# self.searchDisplay = TrademarkSearchDisplay()
|
|
self.searchDisplayWidget = ResultWidget()
|
|
self.currencyInfoObject = ExchangeRateScraper()
|
|
|
|
self.favoriteDelv = ""
|
|
|
|
self.cargo_font = QFont()
|
|
self.cargo_font_size = self.fontSize + 2
|
|
|
|
self.deliveryFees = {}
|
|
|
|
self.initSettings()
|
|
|
|
self.initUI()
|
|
self.loadDeliveryFees()
|
|
self.setDefaultValues()
|
|
self.kipris_Visible()
|
|
|
|
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
|
|
|
|
# self.setAddInterval(self.addFeeInterval)
|
|
# self.setAddMoneySetting(self.addFee)
|
|
self.setFontSize(self.fontSize)
|
|
self.font_size_spinbox.setValue(self.fontSize)
|
|
self.addMoney1_spinbox.setValue(self.addFeeSetting)
|
|
self.addMoney2_spinbox.setValue(self.addFeeInterval)
|
|
self.addMoney3_spinbox.setValue(self.addFee)
|
|
self.saveSettingSwitch.setChecked(self.setSaveSetting)
|
|
self.step_interval_spinbox.setValue(self.weightInterval)
|
|
self.maxVolume_spinbox.setValue(self.maxVolumeSet)
|
|
self.maxWeight_spinbox.setValue(self.maxWeightSet)
|
|
self.maxLength_spinbox.setValue(self.maxLengthSet)
|
|
self.setComboBox()
|
|
|
|
def initSettings(self):
|
|
# self.settings = QtCore.QSettings('When_Ride_Mycar_Tanya', 'DeliveryFeeCalculator')
|
|
self.loadSettings()
|
|
self.load_history()
|
|
|
|
self.user_settings = {
|
|
'use_kipris': self.use_kipris,
|
|
'usage_mode': self.usage_mode,
|
|
'api_key': self.api_key,
|
|
'set_status': self.set_status,
|
|
}
|
|
self.settingDialog = SettingsDialog(parent=self, initial_settings=self.user_settings)
|
|
|
|
currencis = ['USD','CNY']
|
|
self.currencyInfoObject.getCurrency(currencis)
|
|
self.setUSD = self.currencyInfoObject.currencyInfo['USD']['basePrice']
|
|
logger.debug(f"setUSD : {self.setUSD}")
|
|
self.setCNY = self.currencyInfoObject.currencyInfo['CNY']['basePrice']
|
|
logger.debug(f"setCNY : {self.setCNY}")
|
|
self.currentCurrency = self.setCNY
|
|
|
|
def saveSettings(self):
|
|
""" 설정을 JSON 파일에 저장합니다. """
|
|
try:
|
|
settings = {
|
|
'Settings': {
|
|
'maxWeightSet': self.maxWeightSet,
|
|
'maxLengthSet': self.maxLengthSet,
|
|
'maxVolumeSet': self.maxVolumeSet,
|
|
'addFeeInterval': self.addFeeInterval,
|
|
'addFeeSetting': self.addFeeSetting,
|
|
'addFee': self.addFee,
|
|
'fontSize': self.fontSize,
|
|
'weightInterval': self.weightInterval,
|
|
'setSaveSetting': self.setSaveSetting,
|
|
'favoriteDelv': self.favoriteDelv,
|
|
},
|
|
'Kipris': {
|
|
'use_kipris': self.use_kipris,
|
|
'usage_mode': self.usage_mode,
|
|
'api_key': self.api_key,
|
|
'set_status': self.set_status,
|
|
}
|
|
}
|
|
|
|
with open(self.config_path, 'w') as config_file:
|
|
json.dump(settings, config_file, indent=4)
|
|
|
|
logger.info("설정이 성공적으로 저장되었습니다.")
|
|
except Exception as e:
|
|
logger.error(f"설정을 저장하는 중 오류가 발생했습니다: {e}", exc_info=True)
|
|
|
|
def loadSettings(self):
|
|
""" 설정 파일을 불러옵니다. """
|
|
try:
|
|
if not os.path.exists(self.config_path):
|
|
self.create_default_settings()
|
|
|
|
with open(self.config_path, 'r') as config_file:
|
|
settings = json.load(config_file)
|
|
|
|
s = settings['Settings']
|
|
self.maxWeightSet = s['maxWeightSet']
|
|
self.maxLengthSet = s['maxLengthSet']
|
|
self.maxVolumeSet = s['maxVolumeSet']
|
|
self.addFeeInterval = s['addFeeInterval']
|
|
self.addFeeSetting = s['addFeeSetting']
|
|
self.addFee = s['addFee']
|
|
self.fontSize = s['fontSize']
|
|
self.weightInterval = s['weightInterval']
|
|
self.setSaveSetting = s['setSaveSetting']
|
|
self.favoriteDelv = s['favoriteDelv']
|
|
|
|
k = settings['Kipris']
|
|
self.use_kipris = k['use_kipris']
|
|
self.usage_mode = k['usage_mode']
|
|
self.api_key = k['api_key']
|
|
self.set_status = k['set_status']
|
|
|
|
logger.info("설정이 성공적으로 불러와졌습니다.")
|
|
except Exception as e:
|
|
logger.error(f"설정을 불러오는 중 오류가 발생했습니다: {e}", exc_info=True)
|
|
|
|
def create_default_settings(self):
|
|
""" 기본 설정을 생성합니다. """
|
|
settings = {
|
|
'Settings': {
|
|
'maxWeightSet': 25,
|
|
'maxLengthSet': 100,
|
|
'maxVolumeSet': 160,
|
|
'addFeeInterval': 5,
|
|
'addFeeSetting': 20,
|
|
'addFee': 1000,
|
|
'fontSize': 14,
|
|
'weightInterval': 0.5,
|
|
'setSaveSetting': False,
|
|
'favoriteDelv': "노빠꾸해운(배송비)"
|
|
},
|
|
'Kipris': {
|
|
'use_kipris': False,
|
|
'usage_mode': 'web',
|
|
'api_key': '',
|
|
'set_status': ['등록'],
|
|
}
|
|
}
|
|
|
|
with open(self.config_path, 'w') as config_file:
|
|
json.dump(settings, config_file, indent=4)
|
|
|
|
logger.info("기본 설정이 생성되었습니다.")
|
|
|
|
# def loadSettings_ini(self):
|
|
# """ 설정 파일을 불러옵니다. """
|
|
# try:
|
|
# if not os.path.exists(self.config_path):
|
|
# self.create_default_settings()
|
|
# self.config.read(self.config_path)
|
|
|
|
# self.maxWeightSet = self.config.getint('Settings', 'maxWeightSet', fallback=25)
|
|
# self.maxLengthSet = self.config.getint('Settings', 'maxLengthSet', fallback=100)
|
|
# self.maxVolumeSet = self.config.getint('Settings', 'maxVolumeSet', fallback=160)
|
|
# self.addFeeInterval = self.config.getint('Settings', 'addFeeInterval', fallback=5)
|
|
# self.addFeeSetting = self.config.getint('Settings', 'addFeeSetting', fallback=20)
|
|
# self.addFee = self.config.getint('Settings', 'addFee', fallback=1000)
|
|
# self.fontSize = self.config.getint('Settings', 'fontSize', fallback=14)
|
|
# self.weightInterval = self.config.getfloat('Settings', 'weightInterval', fallback=0.5)
|
|
# self.setSaveSetting = self.config.getboolean('Settings', 'setSaveSetting', fallback=False)
|
|
# self.favoriteDelv = self.config.get('Settings', 'favoriteDelv', fallback="노빠꾸해운(배송비)")
|
|
# self.use_kipris = self.config.getboolean('Kipris', 'use_Kipris', fallback=False)
|
|
# self.usage_mode = self.config.get('Kipris', 'usage_mode', fallback="web")
|
|
# self.api_key = self.config.get('Kipris', 'api_key', fallback="")
|
|
# self.set_status = self.config.get('Kipris', 'set_status', fallback="[등록]")
|
|
|
|
# # logger.debug(f"use_kipris : {self.use_kipris}, usage_mode : {self.usage_mode}, api_key : {self.api_key}")
|
|
# except Exception as e:
|
|
# logger.error(f"설정을 불러오는 중 오류가 발생했습니다: {e}", exc_info=True)
|
|
|
|
# def saveSettings_ini(self):
|
|
# """ 설정을 config.ini 파일에 저장합니다. """
|
|
# try:
|
|
# if not self.config.has_section('Settings'):
|
|
# self.config.add_section('Settings')
|
|
|
|
# self.config.set('Settings', 'maxWeightSet', str(self.maxWeightSet))
|
|
# self.config.set('Settings', 'maxLengthSet', str(self.maxLengthSet))
|
|
# self.config.set('Settings', 'maxVolumeSet', str(self.maxVolumeSet))
|
|
# self.config.set('Settings', 'addFeeInterval', str(self.addFeeInterval))
|
|
# self.config.set('Settings', 'addFeeSetting', str(self.addFeeSetting))
|
|
# self.config.set('Settings', 'addFee', str(self.addFee))
|
|
# self.config.set('Settings', 'fontSize', str(self.fontSize))
|
|
# self.config.set('Settings', 'weightInterval', str(self.weightInterval))
|
|
# self.config.set('Settings', 'setSaveSetting', str(self.setSaveSetting))
|
|
# self.config.set('Settings', 'favoriteDelv', str(self.favoriteDelv))
|
|
|
|
# if not self.config.has_section('Kipris'):
|
|
# self.config.add_section('Kipris')
|
|
|
|
# self.config.set('Kipris', 'use_kipris', str(self.use_kipris))
|
|
# self.config.set('Kipris', 'usage_mode', str(self.usage_mode))
|
|
# self.config.set('Kipris', 'api_key', str(self.api_key))
|
|
# self.config.set('Kipris', 'set_status', str(self.set_status))
|
|
|
|
# with open(self.config_path, 'w') as configfile:
|
|
# self.config.write(configfile)
|
|
# except Exception as e:
|
|
# logger.error(f"설정을 저장하는 중 오류가 발생했습니다: {e}", exc_info=True)
|
|
|
|
|
|
# def create_default_settings_ini(self):
|
|
# """ 기본 설정을 생성합니다. """
|
|
# self.config['Settings'] = {
|
|
# 'maxWeightSet': '25',
|
|
# 'maxLengthSet': '100',
|
|
# 'maxVolumeSet': '160',
|
|
# 'addFeeInterval': '5',
|
|
# 'addFeeSetting': '20',
|
|
# 'addFee': '1000',
|
|
# 'fontSize': '14',
|
|
# 'weightInterval': '0.5',
|
|
# 'setSaveSetting': 'False',
|
|
# 'favoriteDelv': "노빠꾸해운(배송비)",
|
|
# }
|
|
# self.config['Kipris'] = {
|
|
# 'use_kipris': 'False',
|
|
# 'usage_mode': 'web',
|
|
# 'api_key': '',
|
|
# 'set_status': '[등록]',
|
|
# }
|
|
|
|
# with open(self.config_path, 'w') as configfile:
|
|
# self.config.write(configfile)
|
|
|
|
def add_history(self, keyword) :
|
|
if keyword:
|
|
if keyword and keyword not in self.history: # 중복된 검색어가 아니면 추가
|
|
self.history.append(keyword)
|
|
logger.debug(f"검색어 [{keyword}] 히스토리에 추가")
|
|
|
|
def load_history(self):
|
|
try:
|
|
with open("search_history.json", "r") as file:
|
|
self.history = json.load(file)
|
|
logger.debug(f"self.history file loaded{self.history}")
|
|
|
|
except (FileNotFoundError, json.JSONDecodeError):
|
|
self.history = []
|
|
logger.debug(f"self.history{self.history}")
|
|
|
|
def save_history(self):
|
|
with open("search_history.json", "w") as file:
|
|
json.dump(self.history, file)
|
|
|
|
def show_history_menu(self, event):
|
|
if self.history:
|
|
menu = QtWidgets.QMenu(self)
|
|
for keyword in self.history:
|
|
menu.addAction(keyword, lambda k=keyword: self.kipris_edit.setText(k))
|
|
menu.exec_(self.kipris_edit.mapToGlobal(event.pos()))
|
|
|
|
def closeEvent(self, event):
|
|
# 설정 저장 여부 로그 기록
|
|
if self.setSaveSetting:
|
|
logger.debug("설정값 저장")
|
|
self.saveSettings() # 설정 저장
|
|
# self.saveWindowSettings() # 필요한 경우 윈도우 설정 저장
|
|
else:
|
|
logger.debug("설정값 저장하지 않음")
|
|
|
|
# 검색 히스토리 저장
|
|
self.save_history()
|
|
|
|
# 부모 클래스의 종료 이벤트 처리 호출
|
|
super().closeEvent(event)
|
|
|
|
# 이벤트 처리 완료를 알림
|
|
event.accept()
|
|
|
|
def initUI(self):
|
|
self.resize(300, 600) # 창 크기 조정
|
|
self.center()
|
|
|
|
# 메뉴바 생성
|
|
menubar = QtWidgets.QMenuBar(self)
|
|
helpMenu = menubar.addMenu('도움말')
|
|
kiprisMenu = menubar.addMenu('키프리스')
|
|
|
|
# 도움말 - 도움말 보기 메뉴 아이템
|
|
helpnemu_helpAction = QtWidgets.QAction('도움말 보기', self)
|
|
helpnemu_helpAction.triggered.connect(self.showHelp)
|
|
helpMenu.addAction(helpnemu_helpAction)
|
|
# 도움말 - ChangeLog 메뉴 아이템
|
|
helpnemu_changelogAction = QtWidgets.QAction('ChangeLog', self)
|
|
helpnemu_changelogAction.triggered.connect(self.showChangeLog)
|
|
helpMenu.addAction(helpnemu_changelogAction)
|
|
# 도움말 - 기본값 설정 메뉴 아이템
|
|
helpnemu_defaultAction = QtWidgets.QAction('기본값 설정', self)
|
|
helpnemu_defaultAction.triggered.connect(self.setttingTosetDefaultValues)
|
|
helpMenu.addAction(helpnemu_defaultAction)
|
|
|
|
# # '설정창 열기' 메뉴 아이템
|
|
openSettingsAction = QtWidgets.QAction('설정창 열기', self)
|
|
openSettingsAction.triggered.connect(self.showSettingsDialog)
|
|
kiprisMenu.addAction(openSettingsAction)
|
|
|
|
|
|
|
|
|
|
# # 키프리스 - APIKEY 메뉴 아이템
|
|
# kiprismenu_settingAction = QtWidgets.QAction('키프리스 ', self)
|
|
# kiprismenu_settingAction.triggered.connect(self.showHelp)
|
|
# kiprisMenu.addAction(kiprismenu_settingAction)
|
|
# # 도움말 - ChangeLog 메뉴 아이템
|
|
# changelogAction = QtWidgets.QAction('ChangeLog', self)
|
|
# changelogAction.triggered.connect(self.showChangeLog)
|
|
# kiprisMenu.addAction(changelogAction)
|
|
# # 도움말 - 기본값 설정 메뉴 아이템
|
|
# defaultAction = QtWidgets.QAction('기본값 설정', self)
|
|
# defaultAction.triggered.connect(self.setttingTosetDefaultValues)
|
|
# kiprisMenu.addAction(defaultAction)
|
|
|
|
|
|
|
|
|
|
# 레이아웃 전체 설정
|
|
self.layout = QtWidgets.QVBoxLayout(self)
|
|
self.layout.setMenuBar(menubar)
|
|
|
|
# 사용자 인터페이스 프레임
|
|
self.user_frame = QtWidgets.QFrame(self)
|
|
self.user_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
|
self.user_frame.setFrameShadow(QtWidgets.QFrame.Raised)
|
|
self.user_layout = QtWidgets.QVBoxLayout(self.user_frame)
|
|
|
|
# 콤보박스 초기화
|
|
self.comboBox = QtWidgets.QComboBox()
|
|
self.comboBox.currentIndexChanged.connect(self.updateComboBox) # 값이 변경될 때 이벤트 연결
|
|
self.user_layout.addWidget(self.comboBox)
|
|
|
|
# 무게입력 박스 초기화
|
|
self.weightInput = QtWidgets.QDoubleSpinBox()
|
|
self.weightInput.setMinimum(0.5)
|
|
self.weightInput.setMaximum(1000)
|
|
self.weightInput.setSingleStep(self.weightInterval)
|
|
self.weightInput.setSuffix(" Kg")
|
|
self.weightInput.valueChanged.connect(self.updateDeliveryFee) # 값이 변경될 때 이벤트 연결
|
|
|
|
self.user_layout.addWidget(self.weightInput)
|
|
|
|
# 부피 입력 칸: 가로, 세로, 높이
|
|
self.dimension_layout = QtWidgets.QHBoxLayout()
|
|
|
|
# 길이 레이아웃
|
|
self.lengthInput = QtWidgets.QSpinBox()
|
|
self.lengthInput.setMinimum(1)
|
|
self.lengthInput.setMaximum(10000)
|
|
self.lengthInput.setSuffix(" cm")
|
|
self.lengthInput.valueChanged.connect(self.updateVolume)
|
|
self.lengthInput_layout = self.create_label_and_spin_in_QV("가로(cm):", self.lengthInput)
|
|
self.dimension_layout.addLayout(self.lengthInput_layout)
|
|
|
|
# 넓이 레이아웃
|
|
self.widthInput = QtWidgets.QSpinBox()
|
|
self.widthInput.setMinimum(1)
|
|
self.widthInput.setMaximum(10000)
|
|
self.widthInput.setSuffix(" cm")
|
|
self.widthInput.valueChanged.connect(self.updateVolume)
|
|
self.widthInput_layout = self.create_label_and_spin_in_QV("세로(cm):", self.widthInput)
|
|
self.dimension_layout.addLayout(self.widthInput_layout)
|
|
|
|
# 높이 레이아웃
|
|
self.heightInput = QtWidgets.QSpinBox()
|
|
self.heightInput.setMinimum(1)
|
|
self.heightInput.setMaximum(10000)
|
|
self.heightInput.setSuffix(" cm")
|
|
self.heightInput.valueChanged.connect(self.updateVolume)
|
|
self.heightInput_layout = self.create_label_and_spin_in_QV("높이(cm):", self.heightInput)
|
|
self.dimension_layout.addLayout(self.heightInput_layout)
|
|
|
|
# 리셋 레이아웃
|
|
self.reset_layout = QtWidgets.QVBoxLayout()
|
|
|
|
self.reset_label = QtWidgets.QLabel("리셋")
|
|
self.reset_layout.addWidget(self.reset_label)
|
|
|
|
self.reset_button = QtWidgets.QPushButton("Reset")
|
|
self.reset_label.setAlignment(QtCore.Qt.AlignCenter)
|
|
self.reset_button.clicked.connect(self.reset_action)
|
|
self.reset_layout.addWidget(self.reset_button)
|
|
self.dimension_layout.addLayout(self.reset_layout)
|
|
|
|
self.user_layout.addLayout(self.dimension_layout)
|
|
|
|
# 레이아웃 비율 설정
|
|
self.dimension_layout.setStretch(0, 3) # 길이 입력 칸
|
|
self.dimension_layout.setStretch(1, 3) # 너비 입력 칸
|
|
self.dimension_layout.setStretch(2, 3) # 높이 입력 칸
|
|
self.dimension_layout.setStretch(3, 1) # 새로 추가된 리셋 레이아웃
|
|
|
|
|
|
# 사용자 정보 프레임
|
|
self.user_info_frame = QtWidgets.QFrame(self)
|
|
self.user_info_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
|
self.user_info_frame.setFrameShadow(QtWidgets.QFrame.Sunken)
|
|
self.user_info_layout = QtWidgets.QVBoxLayout(self.user_info_frame)
|
|
|
|
|
|
# 배송비 레이이웃 추가 설정 중
|
|
self.final_delv_fee_layout = QtWidgets.QHBoxLayout()
|
|
self.deliveryFeeLabel = QtWidgets.QLabel("배송비: 정보 없음")
|
|
self.deliveryFeeADDLabel = QtWidgets.QLabel(f"가중치: {self.addFee}원")
|
|
self.deliveryFeeADDLabel.setVisible(False)
|
|
self.final_delv_fee_layout.addWidget(self.deliveryFeeLabel)
|
|
self.final_delv_fee_layout.addWidget(self.deliveryFeeADDLabel)
|
|
self.user_info_layout.addLayout(self.final_delv_fee_layout)
|
|
|
|
# 부피 라벨
|
|
self.volumeLabel = QtWidgets.QLabel("부피무게: 정보 없음")
|
|
self.user_info_layout.addWidget(self.volumeLabel)
|
|
|
|
# 크기 라벨
|
|
self.maxLengthLabel = QtWidgets.QLabel("한 변의 최대길이 : 정보없음")
|
|
self.maxLengthLabel.setVisible(False)
|
|
self.user_info_layout.addWidget(self.maxLengthLabel)
|
|
|
|
# 추가운임 정보 라벨
|
|
self.additionalFeeTextLabel = QtWidgets.QLabel("화물택배(경동)추가운임 발생. 모든값은 참고치입니다.")
|
|
self.additionalFeeTextLabel.setVisible(False)
|
|
self.user_info_layout.addWidget(self.additionalFeeTextLabel)
|
|
|
|
# 추가운임 라벨
|
|
self.additionalFeeLabel = QtWidgets.QLabel("화물택배(경동)추가운임")
|
|
self.additionalFeeLabel.setVisible(False)
|
|
self.user_info_layout.addWidget(self.additionalFeeLabel)
|
|
|
|
# 설정 프레임
|
|
self.setting_frame = QtWidgets.QFrame(self)
|
|
self.setting_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
|
self.setting_frame.setFrameShadow(QtWidgets.QFrame.Raised)
|
|
self.setting_layout = QtWidgets.QVBoxLayout(self.setting_frame)
|
|
|
|
# 폰트 크기 설정 스핀박스
|
|
self.font_size_spinbox = QtWidgets.QSpinBox()
|
|
self.font_size_spinbox.setRange(10, 50)
|
|
self.font_size_spinbox.setValue(self.fontSize)
|
|
self.font_size_spinbox.valueChanged.connect(self.setFontSize)
|
|
self.font_size_spinbox_layout = self.create_label_and_spin("폰트 크기", self.font_size_spinbox)
|
|
self.setting_layout.addLayout(self.font_size_spinbox_layout)
|
|
|
|
# 스텝 간격 조정 스핀박스
|
|
self.step_interval_spinbox = QtWidgets.QDoubleSpinBox()
|
|
self.step_interval_spinbox.setRange(0.5, 10)
|
|
self.step_interval_spinbox.setSingleStep(0.5)
|
|
self.step_interval_spinbox.setValue(0.5)
|
|
self.step_interval_spinbox.setSuffix(" Kg")
|
|
self.step_interval_spinbox.valueChanged.connect(self.setStepInterval)
|
|
self.step_interval_spinbox_layout = self.create_label_and_spin("무게 간격", self.step_interval_spinbox)
|
|
self.setting_layout.addLayout(self.step_interval_spinbox_layout)
|
|
|
|
# 경동택배 기준설정
|
|
self.cargo_Layout = QtWidgets.QHBoxLayout()
|
|
self.cargoLabel_upper = QtWidgets.QLabel()
|
|
self.cargoLabel = QtWidgets.QLabel()
|
|
self.cargoLabel_bottom = QtWidgets.QLabel()
|
|
self.cargoLabel.setText("경동택배 설정")
|
|
self.cargoLabel.setAlignment(QtCore.Qt.AlignCenter)
|
|
self.cargo_font.setPointSize(self.cargo_font_size) # 폰트 크기를 16포인트로 설정
|
|
self.cargoLabel.setFont(self.cargo_font)
|
|
|
|
self.cargoLabel.setStyleSheet("background-color: lightgrey;")
|
|
|
|
self.cargo_Layout.addWidget(self.cargoLabel_upper)
|
|
self.cargo_Layout.addWidget(self.cargoLabel)
|
|
self.cargo_Layout.addWidget(self.cargoLabel_bottom)
|
|
self.setting_layout.addLayout(self.cargo_Layout)
|
|
|
|
# 경동택배 길이기준 조정 스핀박스
|
|
self.maxLength_spinbox = QtWidgets.QSpinBox()
|
|
self.maxLength_spinbox.setRange(80, 200)
|
|
self.maxLength_spinbox.setSingleStep(5)
|
|
self.maxLength_spinbox.setValue(100)
|
|
self.maxLength_spinbox.setSuffix(" cm")
|
|
self.maxLength_spinbox.valueChanged.connect(self.setMaxLength)
|
|
self.maxLength_spinbox_layout = self.create_label_and_spin("경동한변길이 설정", self.maxLength_spinbox)
|
|
self.setting_layout.addLayout(self.maxLength_spinbox_layout)
|
|
|
|
# 경동택배 부피기준 조정 스핀박스
|
|
self.maxVolume_spinbox = QtWidgets.QSpinBox()
|
|
self.maxVolume_spinbox.setRange(140, 200)
|
|
self.maxVolume_spinbox.setSingleStep(5)
|
|
self.maxVolume_spinbox.setValue(160)
|
|
self.maxVolume_spinbox.setSuffix(" cm")
|
|
self.maxVolume_spinbox.valueChanged.connect(self.setMaxVolume)
|
|
self.maxVolume_spinbox_layout = self.create_label_and_spin("경동(세변합)기준 설정", self.maxVolume_spinbox)
|
|
self.setting_layout.addLayout(self.maxVolume_spinbox_layout)
|
|
|
|
# 경동택배 무게기준 조정 스핀박스
|
|
self.maxWeight_spinbox = QtWidgets.QSpinBox()
|
|
self.maxWeight_spinbox.setRange(10, 50)
|
|
self.maxWeight_spinbox.setSingleStep(1)
|
|
self.maxWeight_spinbox.setValue(25)
|
|
self.maxWeight_spinbox.setSuffix(" Kg")
|
|
self.maxWeight_spinbox.valueChanged.connect(self.setMaxWeight)
|
|
self.maxWeight_spinbox_layout = self.create_label_and_spin("경동무게기준 설정", self.maxWeight_spinbox)
|
|
self.setting_layout.addLayout(self.maxWeight_spinbox_layout)
|
|
|
|
# 가중치 스핀박스
|
|
self.addMoneySetlayout1 = QtWidgets.QHBoxLayout()
|
|
self.addMoneySetlayout2 = QtWidgets.QHBoxLayout()
|
|
self.addMoneySetlayout3 = QtWidgets.QHBoxLayout()
|
|
self.label1 = QtWidgets.QLabel("가중치 기준")
|
|
self.label2 = QtWidgets.QLabel(" 초과시 ")
|
|
|
|
self.label3 = QtWidgets.QLabel(" 마다 ")
|
|
|
|
self.label4 = QtWidgets.QLabel("추가")
|
|
self.addMoney1_spinbox = QtWidgets.QSpinBox()
|
|
self.addMoney1_spinbox.setRange(0, 1000)
|
|
self.addMoney1_spinbox.setSingleStep(1)
|
|
self.addMoney1_spinbox.setValue(20)
|
|
self.addMoney1_spinbox.setSuffix(" Kg")
|
|
self.addMoney1_spinbox.valueChanged.connect(self.setAddMoneySetting)
|
|
self.addMoney2_spinbox = QtWidgets.QSpinBox()
|
|
self.addMoney2_spinbox.setRange(0, 1000)
|
|
self.addMoney2_spinbox.setSingleStep(1)
|
|
self.addMoney2_spinbox.setValue(5)
|
|
self.addMoney2_spinbox.setSuffix(" Kg")
|
|
self.addMoney2_spinbox.valueChanged.connect(self.setAddInterval)
|
|
self.addMoney3_spinbox = QtWidgets.QSpinBox()
|
|
self.addMoney3_spinbox.setRange(0, 100000)
|
|
self.addMoney3_spinbox.setSingleStep(1000)
|
|
self.addMoney3_spinbox.setValue(1000)
|
|
self.addMoney3_spinbox.setSuffix(" 원")
|
|
self.addMoney3_spinbox.valueChanged.connect(self.setAddMoney)
|
|
self.addMoneySetlayout1.addWidget(self.label1)
|
|
self.addMoneySetlayout1.addWidget(self.addMoney1_spinbox)
|
|
self.addMoneySetlayout2.addWidget(self.label2)
|
|
self.addMoneySetlayout2.addWidget(self.addMoney2_spinbox)
|
|
self.addMoneySetlayout3.addWidget(self.label3)
|
|
self.addMoneySetlayout3.addWidget(self.label4)
|
|
self.addMoneySetlayout3.addWidget(self.addMoney3_spinbox)
|
|
self.addMoneySetlayout3.setStretch(0, 6)
|
|
self.addMoneySetlayout3.setStretch(1, 2)
|
|
self.addMoneySetlayout3.setStretch(2, 4)
|
|
self.setting_layout.addLayout(self.addMoneySetlayout1)
|
|
self.setting_layout.addLayout(self.addMoneySetlayout2)
|
|
self.setting_layout.addLayout(self.addMoneySetlayout3)
|
|
|
|
# 키프리스 프레임
|
|
self.kiprisWidget = QtWidgets.QWidget(self)
|
|
self.kipris_layout = QtWidgets.QHBoxLayout(self.kiprisWidget)
|
|
self.kiprisWidget.setLayout(self.kipris_layout)
|
|
self.kiprisWidget.setVisible(False)
|
|
self.kipris_label = QtWidgets.QLabel(f"키프리스 검색")
|
|
self.kipris_edit = QtWidgets.QLineEdit()
|
|
self.kipris_btn = QtWidgets.QPushButton("검색")
|
|
self.kipris_btn.clicked.connect(self.kipris_btn_clicked)
|
|
self.kipris_edit.returnPressed.connect(self.kipris_btn_clicked)
|
|
self.kipris_edit.mousePressEvent = self.show_history_menu
|
|
self.kipris_layout.addWidget(self.kipris_label)
|
|
self.kipris_layout.addWidget(self.kipris_edit)
|
|
self.kipris_layout.addWidget(self.kipris_btn)
|
|
self.kipris_layout.setStretch(0,3)
|
|
self.kipris_layout.setStretch(1,6)
|
|
self.kipris_layout.setStretch(2,3)
|
|
# self.setting_layout.addLayout(self.kipris_layout)
|
|
self.setting_layout.addWidget(self.kiprisWidget) # self.kiprisWidget을 설정 레이아웃에 추가
|
|
|
|
|
|
# 추가정보 프레임
|
|
self.addInfoWidget = QtWidgets.QWidget(self)
|
|
self.addInfo_vlayout = QtWidgets.QVBoxLayout(self.addInfoWidget)
|
|
self.addInfo_h1layout = QtWidgets.QHBoxLayout()
|
|
self.addInfo_h2layout = QtWidgets.QHBoxLayout()
|
|
self.addInfo_vlayout.addLayout(self.addInfo_h2layout)
|
|
self.addInfo_vlayout.addLayout(self.addInfo_h1layout)
|
|
self.addInfoWidget.setLayout(self.addInfo_vlayout)
|
|
self.addInfoWidget.setVisible(True)
|
|
self.setUSD_label = QtWidgets.QLabel(f"[{self.setUSD}]USD/KRW")
|
|
setUSD_label_font = QFont()
|
|
setUSD_label_font.setBold(True) # 굵게
|
|
setUSD_label_font.setUnderline(True) # 밑줄
|
|
setUSD_label_font.setWeight(12) # 폰트크기
|
|
self.setUSD_label.setAlignment(QtCore.Qt.AlignCenter) # 가운데 정렬
|
|
self.setUSD_label.setFont(setUSD_label_font) # 폰트 적용
|
|
self.addInfo_h1layout.addWidget(self.setUSD_label)
|
|
self.setCNY_label = QtWidgets.QLabel(f"[{self.setCNY}]CNY/KRW")
|
|
setCNY_label_font = QFont()
|
|
setCNY_label_font.setBold(True) # 굵게
|
|
setCNY_label_font.setUnderline(True) # 밑줄
|
|
setCNY_label_font.setWeight(12) # 폰트크기
|
|
self.setCNY_label.setAlignment(QtCore.Qt.AlignCenter) # 가운데 정렬
|
|
self.setCNY_label.setFont(setCNY_label_font) # 폰트 적용
|
|
self.addInfo_h1layout.addWidget(self.setCNY_label)
|
|
self.addInfo1_btn = QtWidgets.QPushButton("금지어")
|
|
self.addInfo1_btn.clicked.connect(self.addInfo1_btn_clicked)
|
|
self.addInfo_h2layout.addWidget(self.addInfo1_btn)
|
|
self.addInfo2_btn = QtWidgets.QPushButton("도량형")
|
|
self.addInfo2_btn.clicked.connect(self.addInfo2_btn_clicked)
|
|
self.addInfo_h2layout.addWidget(self.addInfo2_btn)
|
|
self.addInfo3_btn = QtWidgets.QPushButton("타냐어록")
|
|
self.addInfo3_btn.setEnabled(False)
|
|
self.addInfo3_btn.clicked.connect(self.addInfo3_btn_clicked)
|
|
self.addInfo_h2layout.addWidget(self.addInfo3_btn)
|
|
self.addInfo4_btn = QtWidgets.QPushButton("딥러닝번역")
|
|
self.addInfo4_btn.setEnabled(False)
|
|
self.addInfo4_btn.clicked.connect(self.addInfo4_btn_clicked)
|
|
self.addInfo_h2layout.addWidget(self.addInfo4_btn)
|
|
# self.addInfo_layout.setStretch(0,3)
|
|
# self.addInfo_layout.setStretch(1,6)
|
|
# self.addInfo_layout.setStretch(2,3)
|
|
# self.setting_layout.addLayout(self.addInfo_layout)
|
|
self.setting_layout.addWidget(self.addInfoWidget) # self.addInfoWidget 설정 레이아웃에 추가
|
|
|
|
|
|
# 경동택배 무게기준 조정 스핀박스
|
|
self.changeCurreny_btn = QtWidgets.QPushButton("CNY/KRW")
|
|
self.changeCurreny_btn.clicked.connect(self.changeCurreny_btn_clicked)
|
|
|
|
self.calcCurrency_label = QtWidgets.QLabel("")
|
|
self.calcCurrency_label.setText(" 원")
|
|
self.calcCurrency_label.setAlignment(QtCore.Qt.AlignCenter)
|
|
calcCurrency_label_font = QFont()
|
|
calcCurrency_label_font.setBold(True) # 굵게
|
|
calcCurrency_label_font.setUnderline(True) # 밑줄
|
|
calcCurrency_label_font.setWeight(16) # 폰트크기
|
|
self.calcCurrency_label.setFont(calcCurrency_label_font)
|
|
|
|
self.currency_calc_box = QtWidgets.QSpinBox()
|
|
self.currency_calc_box.setRange(0, 1000000)
|
|
self.currency_calc_box.setSingleStep(10)
|
|
self.currency_calc_box.setValue(100)
|
|
self.currency_calc_box.setSuffix(" CNY")
|
|
self.currency_calc_box.setAlignment(QtCore.Qt.AlignRight) # 가운데 정렬
|
|
self.currency_calc_box.valueChanged.connect(self.calcCurrency)
|
|
self.currency_calc_box_layout = self.create_label_and_spin("환율", self.currency_calc_box)
|
|
self.currency_calc_box_layout.addWidget(self.calcCurrency_label)
|
|
self.currency_calc_box_layout.addWidget(self.changeCurreny_btn)
|
|
self.currency_calc_box_layout.setStretch(0,2)
|
|
self.currency_calc_box_layout.setStretch(1,4)
|
|
self.currency_calc_box_layout.setStretch(2,4)
|
|
self.currency_calc_box_layout.setStretch(3,2)
|
|
self.setting_layout.addLayout(self.currency_calc_box_layout)
|
|
|
|
# 항상 위에 토글 스위치
|
|
self.alwaysOnTopSwitch = ToggleSwitch(self.setting_frame)
|
|
self.alwaysOnTopSwitch.move(10, 10)
|
|
self.alwaysOnTopSwitch.setChecked(True) # 기본 상태는 ON
|
|
self.alwaysOnTopSwitch.clicked.connect(self.toggleAlwaysOnTop)
|
|
self.alwaysOnTopSwitch_layout = self.create_label_and_switch("항상 위에 표시", self.alwaysOnTopSwitch)
|
|
self.setting_layout.addLayout(self.alwaysOnTopSwitch_layout)
|
|
|
|
# 설정값 저장 토글 스위치
|
|
self.saveSettingSwitch = ToggleSwitch(self.setting_frame)
|
|
self.saveSettingSwitch.move(10, 10)
|
|
self.saveSettingSwitch.setChecked(False) # 기본 상태는 OFF
|
|
self.saveSettingSwitch.clicked.connect(self.isSaveSetting)
|
|
self.saveSettingSwitch_layout = self.create_label_and_switch("설정값 저장", self.saveSettingSwitch)
|
|
self.setting_layout.addLayout(self.saveSettingSwitch_layout)
|
|
|
|
# 낙인
|
|
self.infoLabel4 = QtWidgets.QLabel(" 배송비계산기 by 내차는언제타냐")
|
|
self.setting_layout.addWidget(self.infoLabel4)
|
|
|
|
# 레이아웃 비율 조정
|
|
self.layout.addWidget(self.user_frame, 3)
|
|
self.layout.addWidget(self.user_info_frame, 3)
|
|
self.layout.addWidget(self.setting_frame, 4)
|
|
|
|
self.setWindowTitle('배송비 계산기')
|
|
|
|
# def initSettings_for_kipris_ori(self):
|
|
# if self.kiprisAPI:
|
|
# # 현재 객체가 적절한 타입인지 확인
|
|
# current_type = type(self.kiprisAPI)
|
|
# target_type = Kipris_API if self.usage_mode == 'api' else Kipris_WEB
|
|
|
|
# if current_type is not target_type:
|
|
# # 기존 객체가 다른 타입이면 삭제하고 새로 생성
|
|
# logger.debug(f"기존 {self.kiprisAPI} 객체를 삭제하고 새 객체를 생성합니다.")
|
|
# self.kiprisAPI.close_Kipris() # 기존객체 리소스 정리
|
|
# del self.kiprisAPI # 기존 객체 참조 제거
|
|
# self.kiprisAPI = target_type(self.api_key) # 새 객체 생성
|
|
# logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}")
|
|
# else:
|
|
# logger.debug(f"기존에 적절한 {self.kiprisAPI} 객체가 이미 존재합니다.")
|
|
# else:
|
|
# # 객체가 없으면 새로 생성
|
|
# self.kiprisAPI = Kipris_API(self.api_key) if self.usage_mode == 'api' else Kipris_WEB(self.api_key)
|
|
# logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}")
|
|
|
|
def initSettings_for_kipris(self):
|
|
if self.kiprisAPI:
|
|
# 현재 객체가 적절한 타입인지 확인
|
|
current_type = type(self.kiprisAPI)
|
|
target_type = Kipris_API if self.usage_mode == 'api' else AsyncWebSearchWorker
|
|
|
|
if current_type is not target_type:
|
|
# 기존 객체가 다른 타입이면 삭제하고 새로 생성
|
|
logger.debug(f"기존 {self.kiprisAPI} 객체를 삭제하고 새 객체를 생성합니다.")
|
|
if isinstance(self.kiprisAPI, AsyncWebSearchWorker):
|
|
self.kiprisAPI.deleteLater() # 비동기 작업자는 Qt 객체로 관리되므로 deleteLater 사용
|
|
self.kiprisAPI = None
|
|
if self.usage_mode == 'api':
|
|
self.kiprisAPI = Kipris_API(self.api_key) # 새 객체 생성
|
|
else:
|
|
web_scraper = WebScraper() # WebScraper 인스턴스 생성
|
|
self.web_scraper = web_scraper
|
|
self.kiprisAPI = AsyncWebSearchWorker(self.web_scraper, "") # 초기 키워드는 비워두기
|
|
logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}")
|
|
else:
|
|
logger.debug(f"기존에 적절한 {self.kiprisAPI} 객체가 이미 존재합니다.")
|
|
else:
|
|
# 객체가 없으면 새로 생성
|
|
if self.usage_mode == 'api':
|
|
self.kiprisAPI = Kipris_API(self.api_key)
|
|
else:
|
|
web_scraper = WebScraper() # WebScraper 인스턴스 생성
|
|
self.web_scraper = web_scraper
|
|
self.kiprisAPI = AsyncWebSearchWorker(web_scraper, "") # 초기 키워드는 비워두기
|
|
logger.debug(f"{self.usage_mode.upper()} 방식 kiprisAPI 객체 생성: {self.kiprisAPI}")
|
|
|
|
def addInfo1_btn_clicked(self):
|
|
pass
|
|
|
|
def addInfo2_btn_clicked(self):
|
|
pass
|
|
|
|
def addInfo3_btn_clicked(self):
|
|
pass
|
|
|
|
def addInfo4_btn_clicked(self):
|
|
pass
|
|
|
|
|
|
def showSettingsDialog(self):
|
|
if self.settingDialog.exec_():
|
|
self.use_kipris = self.settingDialog.use_kipris
|
|
self.usage_mode = self.settingDialog.usage_mode
|
|
self.api_key = self.settingDialog.api_key
|
|
self.set_status = self.settingDialog.set_status
|
|
|
|
self.kipris_Visible()
|
|
|
|
def kipris_Visible(self):
|
|
if self.use_kipris:
|
|
self.kiprisWidget.setVisible(True)
|
|
self.initSettings_for_kipris()
|
|
self.kipris_label.setText(f"키프리스 검색({self.usage_mode})")
|
|
else:
|
|
self.kiprisWidget.setVisible(False)
|
|
|
|
def create_label_and_switch(self, label_text, target_switch):
|
|
layout = QtWidgets.QHBoxLayout()
|
|
label = QtWidgets.QLabel(label_text)
|
|
# label.setAlignment(QtCore.Qt.AlignCenter)
|
|
layout.addWidget(label)
|
|
layout.addWidget(target_switch)
|
|
return layout
|
|
|
|
def create_label_and_spin(self, label_text, spin):
|
|
layout = QtWidgets.QHBoxLayout()
|
|
label = QtWidgets.QLabel(label_text)
|
|
# label.setAlignment(QtCore.Qt.AlignCenter)
|
|
layout.addWidget(label)
|
|
layout.addWidget(spin)
|
|
return layout
|
|
|
|
def create_label_and_spin_in_QV(self, label_text, spin):
|
|
layout = QtWidgets.QVBoxLayout()
|
|
label = QtWidgets.QLabel(label_text)
|
|
label.setAlignment(QtCore.Qt.AlignCenter)
|
|
layout.addWidget(label)
|
|
layout.addWidget(spin)
|
|
return layout
|
|
|
|
def center(self):
|
|
qr = self.frameGeometry()
|
|
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
|
|
qr.moveCenter(cp)
|
|
self.move(qr.topLeft())
|
|
|
|
def loadDeliveryFees(self):
|
|
try:
|
|
excel_file = pd.ExcelFile('delv.xlsx')
|
|
sheets = excel_file.sheet_names
|
|
for sheet in sheets:
|
|
df = excel_file.parse(sheet)
|
|
# 시트 내 컬럼 확인 및 데이터 처리
|
|
if '무게' in df.columns and '배송비' in df.columns:
|
|
self.processSheet(df, sheet, '무게')
|
|
if '부피' in df.columns and '배송비' in df.columns:
|
|
self.processSheet(df, sheet, '부피')
|
|
|
|
if sheet.endswith('(배송비)'):
|
|
self.comboBox.addItem(sheet)
|
|
|
|
logger.debug('Excel file loaded successfully.')
|
|
except Exception as e:
|
|
logger.error(f"Error loading Excel file: {e}", exc_info=True)
|
|
QtWidgets.QMessageBox.critical(self, "Error", "Failed to load the Excel file.")
|
|
|
|
def processSheet(self, df, sheet_name, key):
|
|
records = []
|
|
for index, row in df.iterrows():
|
|
try:
|
|
value_str = re.findall(r'\d+[\d,]*', str(row[key]))[0].replace(',', '')
|
|
fee_str = re.findall(r'\d+[\d,]*', str(row['배송비']))[0].replace(',', '')
|
|
value = float(value_str)
|
|
fee = int(fee_str)
|
|
records.append({key: value, '배송비': fee})
|
|
except ValueError as e:
|
|
logger.error(f"Error converting values in row {index} of sheet {sheet_name}: {e}")
|
|
continue
|
|
self.deliveryFees[sheet_name] = records
|
|
|
|
def setDefaultValues(self):
|
|
self.weightInput.setValue(1)
|
|
self.widthInput.setValue(1)
|
|
self.lengthInput.setValue(1)
|
|
self.heightInput.setValue(1)
|
|
|
|
self.updateDeliveryFee()
|
|
|
|
def updateDeliveryFee(self):
|
|
try:
|
|
weight = self.weightInput.value()
|
|
# logger.debug(f"현재 선택된 무게 : {weight}")
|
|
selected_sheet = self.comboBox.currentText()
|
|
# logger.debug(f"현재 선택된 시트 : {selected_sheet}")
|
|
fees = self.deliveryFees.get(selected_sheet, [])
|
|
fee = 0
|
|
# 가능한 모든 무게를 리스트로 가져오고 정렬
|
|
sorted_fees = sorted((float(f['무게']), int(f['배송비'])) for f in fees if '무게' in f and '배송비' in f)
|
|
|
|
# 입력된 무게보다 작거나 같은 최대 무게 찾기
|
|
closest_fee = None
|
|
for w, f in sorted_fees:
|
|
if weight >= w:
|
|
closest_fee = f
|
|
else:
|
|
break
|
|
|
|
# 배송비 업데이트
|
|
if closest_fee is not None:
|
|
fee = closest_fee
|
|
|
|
# 추가 배송비 계산
|
|
if weight > self.addFeeSetting:
|
|
# 추가될 배송비 횟수 계산
|
|
additional_fee_count = (weight - self.addFeeSetting) // self.addFeeInterval
|
|
if (weight - self.addFeeSetting) % self.addFeeInterval != 0:
|
|
additional_fee_count += 1
|
|
total_add_fee = additional_fee_count * self.addFee
|
|
fee += total_add_fee
|
|
self.deliveryFeeLabel.setText(f'배송비: {int(fee): ,}원 (추가 배송비 {int(total_add_fee)} 포함)')
|
|
else:
|
|
self.deliveryFeeLabel.setText(f'배송비: {int(fee): ,}원')
|
|
|
|
# logger.debug(f"배송비 deliveryFeeLabel에 업데이트: {int(fee): ,}원")
|
|
|
|
# 폰트와 밑줄 설정
|
|
font = QFont()
|
|
font.setBold(True) # 굵게
|
|
font.setUnderline(True) # 밑줄
|
|
self.deliveryFeeLabel.setFont(font)
|
|
|
|
self.currentWeight = weight
|
|
self.additionalFee()
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error updating delivery fee: {e}", exc_info=True)
|
|
self.deliveryFeeLabel.setText("배송비 업데이트 중 오류 발생")
|
|
|
|
def updateAdditionalDeliveryFee(self):
|
|
try:
|
|
weight = self.weightInput.value()
|
|
volume = self.currentVolume # 현재 부피
|
|
logger.debug(f"현재 선택된 무게 : {weight}")
|
|
selected_v_sheet = '경동부피'
|
|
selected_w_sheet = '경동무게'
|
|
v_fees = self.deliveryFees.get(selected_v_sheet, [])
|
|
w_fees = self.deliveryFees.get(selected_w_sheet, [])
|
|
# 가능한 모든 무게를 리스트로 가져오고 정렬
|
|
sorted_v_fees = sorted((float(f['부피']), int(f['배송비'])) for f in v_fees if '부피' in f and '배송비' in f)
|
|
sorted_w_fees = sorted((float(f['무게']), int(f['배송비'])) for f in w_fees if '무게' in f and '배송비' in f)
|
|
# logger.debug(f"경동부피무게 가격 : {sorted_v_fees}")
|
|
# logger.debug(f"경동무게당 가격 : {sorted_w_fees}")
|
|
|
|
# 입력된 무게보다 작거나 같은 최대 무게 찾기
|
|
closest_v_fee = None
|
|
closest_w_fee = None
|
|
price_source = ""
|
|
|
|
# 무게에 따른 최적 배송비 계산
|
|
for w_w, w_f in sorted_w_fees:
|
|
if weight >= w_w:
|
|
closest_w_fee = w_f
|
|
else:
|
|
break
|
|
|
|
# 부피에 따른 최적 배송비 계산
|
|
for v_w, v_f in sorted_v_fees:
|
|
if volume >= v_w:
|
|
closest_v_fee = v_f
|
|
else:
|
|
break
|
|
|
|
# 최종 가격 결정 및 가격 출처 확인
|
|
if closest_v_fee is not None and closest_w_fee is not None:
|
|
if closest_v_fee >= closest_w_fee:
|
|
closest_final_fee = closest_v_fee
|
|
price_source = "부피"
|
|
else:
|
|
closest_final_fee = closest_w_fee
|
|
price_source = "무게"
|
|
elif closest_v_fee is not None:
|
|
closest_final_fee = closest_v_fee
|
|
price_source = "부피"
|
|
elif closest_w_fee is not None:
|
|
closest_final_fee = closest_w_fee
|
|
price_source = "무게"
|
|
else:
|
|
closest_final_fee = 0
|
|
price_source = "데이터 없음"
|
|
|
|
# 폰트와 밑줄 설정
|
|
font = QFont()
|
|
font.setBold(True) # 굵게
|
|
font.setUnderline(True) # 밑줄
|
|
self.additionalFeeLabel.setFont(font)
|
|
# 배송비 업데이트 및 라벨 표시
|
|
fee = f"{closest_final_fee: ,}원"
|
|
self.additionalFeeLabel.setText(f'경동 택배비[{price_source}]: {fee}')
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error updating Additional delivery fee: {e}", exc_info=True)
|
|
self.additionalFeeLabel.setText("배송비 업데이트 중 오류 발생")
|
|
|
|
|
|
def updateComboBox(self):
|
|
selected_Delv = self.comboBox.currentText()
|
|
logger.debug(f"선택된 배대지: {selected_Delv}")
|
|
self.favoriteDelv = selected_Delv
|
|
self.updateDeliveryFee()
|
|
|
|
def setComboBox(self):
|
|
logger.debug(f"self.favoriteDelv: {self.favoriteDelv}")
|
|
|
|
if self.favoriteDelv:
|
|
index = self.comboBox.findText(self.favoriteDelv)
|
|
logger.debug(f"저장된 배대지가 존재함: {self.favoriteDelv}")
|
|
if index >= 0:
|
|
self.comboBox.setCurrentIndex(index)
|
|
else:
|
|
logger.debug("저장된 배대지가 엑셀시트에 존재하지 않습니다.")
|
|
|
|
|
|
def additionalFee(self):
|
|
messages = []
|
|
exceeded = False
|
|
|
|
if self.currentWeight >= self.maxWeightSet:
|
|
messages.append(f"무게기준 [{self.maxWeightSet}Kg] 초과")
|
|
exceeded = True
|
|
if self.currentMaxLength >= self.maxLengthSet:
|
|
messages.append(f"길이기준 [{self.maxLengthSet}cm] 초과")
|
|
exceeded = True
|
|
if self.roundVolume >= self.maxVolumeSet:
|
|
logger.debug(f"self.roundVolume : {self.roundVolume}")
|
|
logger.debug(f"maxVolumeSet : {self.maxVolumeSet}")
|
|
messages.append(f"세변의 합 기준 [{self.maxVolumeSet}cm] 초과")
|
|
exceeded = True
|
|
|
|
if exceeded:
|
|
# 모든 메시지를 연결하여 표시
|
|
self.additionalFeeTextLabel.setText(", ".join(messages))
|
|
self.additionalFeeLabel.setVisible(True)
|
|
self.additionalFeeTextLabel.setVisible(True)
|
|
self.updateAdditionalDeliveryFee()
|
|
else:
|
|
self.additionalFeeLabel.setVisible(False)
|
|
self.additionalFeeTextLabel.setVisible(False)
|
|
|
|
|
|
def updateVolume(self):
|
|
length = self.lengthInput.value()
|
|
width = self.widthInput.value()
|
|
height = self.heightInput.value()
|
|
|
|
|
|
volume = length * width * height
|
|
roundVolume = length + width + height
|
|
self.currentVolume = volume
|
|
self.roundVolume = roundVolume
|
|
self.volumeLabel.setText(f"부피: {volume: ,} cm³")
|
|
|
|
self.currentMaxLength = max(length,width,height)
|
|
if self.currentMaxLength > self.maxLengthSet:
|
|
self.maxLengthLabel.setText(f"한 변의 최대길이 : {self.currentMaxLength}cm")
|
|
self.maxLengthLabel.setVisible(True)
|
|
else:
|
|
self.maxLengthLabel.setVisible(False)
|
|
self.additionalFee()
|
|
|
|
def toggleAlwaysOnTop(self, state):
|
|
if state:
|
|
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
|
|
else:
|
|
self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
|
|
self.show() # 변경된 윈도우 플래그를 적용하기 위해 위젯을 다시 보여줘야 함
|
|
|
|
def setFontSize(self, value):
|
|
font = self.font()
|
|
font.setPointSize(value)
|
|
self.setFont(font)
|
|
self.fontSize = value
|
|
self.cargo_font.setPointSize(self.cargo_font_size)
|
|
|
|
def setStepInterval(self, value):
|
|
self.weightInput.setSingleStep(value)
|
|
self.weightInterval = value
|
|
|
|
def setMaxWeight(self, value):
|
|
self.maxWeightSet = value
|
|
self.updateDeliveryFee()
|
|
|
|
def setMaxLength(self, value):
|
|
self.maxLengthSet = value
|
|
self.updateDeliveryFee()
|
|
|
|
def setMaxVolume(self, value):
|
|
self.maxVolumeSet = value
|
|
self.updateDeliveryFee()
|
|
|
|
def setAddMoneySetting(self, value):
|
|
self.addFeeSetting = value
|
|
if self.addFeeSetting == 0:
|
|
self.addFee = 2000
|
|
self.updateDeliveryFee()
|
|
|
|
def setAddMoney(self, value):
|
|
self.addFee = value
|
|
self.updateDeliveryFee()
|
|
|
|
def setAddInterval(self, value):
|
|
self.addFeeInterval = value
|
|
self.updateDeliveryFee()
|
|
|
|
def changeCurreny_btn_clicked(self):
|
|
selected = self.changeCurreny_btn.text()
|
|
if selected == 'CNY/KRW':
|
|
self.currency_calc_box.setSuffix(" USD")
|
|
self.changeCurreny_btn.setText('USD/KRW')
|
|
self.currentCurrency = self.setUSD
|
|
else:
|
|
self.currency_calc_box.setSuffix(" CNY")
|
|
self.changeCurreny_btn.setText('CNY/KRW')
|
|
self.currentCurrency = self.setCNY
|
|
self.calcCurrency(100)
|
|
|
|
def calcCurrency(self,value):
|
|
result = value * self.currentCurrency
|
|
result = round(result,0)
|
|
result = '{0:,}'.format(result)
|
|
# logger.debug(f"result{result}")
|
|
# logger.debug(f"round(result,2){str(round(result,0))}")
|
|
self.calcCurrency_label.setText(result+' 원')
|
|
|
|
def isSaveSetting(self, state):
|
|
if state:
|
|
self.setSaveSetting = True
|
|
else:
|
|
self.setSaveSetting = False
|
|
|
|
logger.debug(f"설정값 저장세팅 : {self.setSaveSetting}")
|
|
self.show()
|
|
|
|
def kipris_btn_clicked(self):
|
|
self.search_keyword = self.kipris_edit.text()
|
|
logger.debug(f"키프리스 검색버튼 클릭 : 키워드 = [{self.search_keyword}]")
|
|
|
|
# result = self.kiprisAPI.run(self.search_keyword, self.set_status)
|
|
# logger.debug(f"result {result}")
|
|
|
|
if self.search_keyword.strip(): # 검색어가 비어있지 않은 경우에만 검색 수행
|
|
logger.debug(f"검색 호출방식 : {self.usage_mode}")
|
|
if self.usage_mode == 'web':
|
|
self.handle_search_for_web(self.search_keyword)
|
|
if self.usage_mode == 'api':
|
|
self.handle_search_for_api(self.search_keyword)
|
|
|
|
def handle_search_for_web(self, keyword):
|
|
self.add_history(keyword) # 검색어 히스토리 추가
|
|
if self.asyncWorker: # 기존에 비동기 작업자가 존재한다면
|
|
self.asyncWorker.thread.quit() # 기존 스레드 종료
|
|
|
|
logger.debug(f"키프리스 검색버튼 클릭 : 키워드 = [{keyword}]")
|
|
self.asyncWorker = AsyncWebSearchWorker(keyword, self.set_status) # 새 비동기 작업자 생성
|
|
self.asyncWorker.finished.connect(self.display_results_for_web) # 완료 시그널을 결과 표시 함수에 연결
|
|
self.asyncWorker.start() # 비동기 작업 시작
|
|
logger.debug("비동기 검색 시작")
|
|
|
|
def display_results_for_web(self, result, elapsed_time):
|
|
# logger.debug(f"result : {result}")
|
|
searchType = 'web'
|
|
logger.debug(f"display_results_for_web - currentURL : {self.web_scraper.currentURL}")
|
|
self.searchDisplayWidget.show_results(result, searchType, elapsed_time, self.web_scraper.currentURL)
|
|
|
|
# self.searchDisplay.display_web_results(result, elapsed_time)
|
|
# self.searchDisplay.show()
|
|
|
|
message = f"검색 결과 : {result}\n검색에 걸린 시간: {elapsed_time:.1f}초"
|
|
# QtWidgets.QMessageBox.information(self, "Search Results", message)
|
|
|
|
self.asyncWorker = None # 작업 완료 후 객체 참조 해제
|
|
|
|
def handle_search_for_api(self, keyword):
|
|
self.add_history(keyword)
|
|
|
|
if self.searchThread is not None and self.searchThread.isRunning():
|
|
self.searchThread.quit() # 이전 스레드가 실행 중이라면 안전하게 종료
|
|
logger.debug("기존 쓰레드가 존재하므로 기존 쓰레드 종료")
|
|
logger.debug(f"키프리스 검색버튼 클릭 : 키워드 = [{keyword}]")
|
|
|
|
worker = APISearchWorker(self.kiprisAPI, keyword, self.set_status)
|
|
|
|
# worker = SearchWorker(self.kiprisAPI, keyword, self.set_status)
|
|
|
|
logger.debug("워커 생성")
|
|
self.searchThread = SearchThread(worker)
|
|
logger.debug("쓰레드 생성")
|
|
worker.finished.connect(self.display_results_for_api)
|
|
self.searchThread.finished.connect(self.clear_thread_reference)
|
|
self.searchThread.start_search()
|
|
logger.debug("검색 시작")
|
|
|
|
def clear_thread_reference(self):
|
|
# 스레드 종료 후 참조를 제거하여 다음 검색을 위해 준비
|
|
self.searchThread = None
|
|
|
|
def display_results_for_api(self, result, elapsed_time):
|
|
searchType = 'api'
|
|
logger.debug(f"display_results_for_api result: {result}")
|
|
self.searchDisplayWidget.show_results(result, searchType, elapsed_time)
|
|
message = f"검색 결과 : {result}\n검색에 걸린 시간: {elapsed_time:.1f}초"
|
|
# QtWidgets.QMessageBox.information(self, "Search Results", message)
|
|
|
|
def reset_action(self):
|
|
self.lengthInput.setValue(1)
|
|
self.widthInput.setValue(1)
|
|
self.heightInput.setValue(1)
|
|
|
|
def showHelp(self):
|
|
# 도움말 내용 표시
|
|
helpText = "안녕하세요 내차는 언제타냐 입니다. \n - 모든 입력칸에는 마우스 휠로 입력가능하고, \n - 컨트롤+휠 동작시 (기본값x10) 값으로 변경가능합니다.\n - 배대지를 추가하려면 첨부된 엑셀파일 delv.xlsx를 참조하세요 \n - 배대지 순서를 정하려면 시트이름에 번호를 붙이세요."
|
|
QtWidgets.QMessageBox.information(self, '도움말', helpText)
|
|
|
|
def showChangeLog(self):
|
|
# ChangeLog 내용 표시
|
|
QtWidgets.QMessageBox.information(self, 'ChangeLog', "Version 1.0 \n Inintial Launch\n\nVersion 1.0.1 \n Dimension에 Reset버튼 추가")
|
|
|
|
def setttingTosetDefaultValues(self):
|
|
# 기본값 설정 로직
|
|
QtWidgets.QMessageBox.information(self, '기본값 설정', "기본값으로 설정합니다.")
|
|
self.font_size_spinbox.setValue(14)
|
|
# self.setFontSize
|
|
self.addMoney1_spinbox.setValue(20)
|
|
self.addMoney2_spinbox.setValue(5)
|
|
self.addMoney3_spinbox.setValue(5000)
|
|
self.saveSettingSwitch.setChecked(False)
|
|
self.step_interval_spinbox.setValue(0.5)
|
|
self.maxVolume_spinbox.setValue(160)
|
|
self.maxWeight_spinbox.setValue(25)
|
|
self.maxLength_spinbox.setValue(100)
|
|
|
|
self.favoriteDelv = None
|
|
self.setComboBox()
|
|
|
|
if __name__ == '__main__':
|
|
minimize_console()
|
|
|
|
app = QtWidgets.QApplication(sys.argv)
|
|
logger = setup_logger('default_logger', 'delivery_calc.log', level=logging.DEBUG)
|
|
ex = DeliveryFeeCalculator(logger)
|
|
ex.show()
|
|
sys.exit(app.exec_())
|