デモ・申請アプリ

投稿者: | 2023-01-15
from datetime import datetime
from dateutil.relativedelta import relativedelta
from pathlib import Path
import PySimpleGUI as sg
import shutil
import sys
import time
import webbrowser

MANUAL_URL = 'https://www.yahoo.co.jp'
DESKTOP = Path().home() / "OneDrive\デスクトップ"
DEFAULT_FOL_1 = r"C:\Users\yoshi\OneDrive\デスクトップ\所定フォルダ1"
DEFAULT_FOL_2 = r"C:\Users\yoshi\OneDrive\デスクトップ\所定フォルダ2"
DEFAULT_FILENAME_KW_1 = ["file", "A", "2211", "txt"]
DEFAULT_FILENAME_KW_2 = ["file", "B", "2211", "txt"]
OUTPUT_FOL = r"C:\Users\yoshi\OneDrive\デスクトップ\OUTPUT"
OUTPUT_FILENAME = "output.txt"

def time_as_int():
    return int(round(time.time() * 100))

def get_ym(yymm: str) -> str:
    while True:
        try:
            houkoku_month_dt = datetime.strptime(yymm, '%y%m')
            two_months_ago_dt = houkoku_month_dt + relativedelta(months=-2)
            kyoukyu_month = two_months_ago_dt.strftime('%y%m')
            return kyoukyu_month
        except Exception as ex:
            sg.popup('YYMM形式で入力してください')
            break

def make_work_folder(yymm: str):
    suffix_now = (datetime.now()).strftime('%m%d%H%M%S')
    work_folder_name = f'交付金申請({yymm}報告分)_{suffix_now}'
    work_folder_p = Path(DESKTOP) / work_folder_name
    work_folder_p.mkdir()
    sg.popup(f'新規フォルダを作成しました\n{work_folder_p}')
    return work_folder_p

def check_filename(filename: str, kwlist: list) -> bool:
    if len(kwlist) > 0:
        ary = []
        for kw in kwlist:
            bool = kw in filename
            ary.append(bool)
        return all(ary)
    else:
        raise IndexError('ファイル名を照会するキーワードがありません')

def copy_to_folder(file_p: str, folder_p: str):
    shutil.copy(file_p, folder_p)

続き

layout = [
    [sg.Text("<作業手順>"), sg.Push(), sg.Text('マニュアルを開く'), sg.Button('Open_Url')],
    [sg.HSep()],
    [sg.Text('1.報告年月を入力する')],
    [sg.Text('報告月(YYMM)'), sg.Input(key='-報告月-', size=(10,1)),sg.Button('Set_YYMM')],
    [sg.Text('供給月(YYMM-2)'), sg.Text(size=(10,1), key='-供給月-'), sg.Push()],
    [sg.HSep()],
    [sg.Text('2.作業フォルダをデスクトップに作成'), sg.Button('New_Folder')],
    [sg.Input(key='-new_folder_p-')],
    [sg.HSep()],
    [sg.Text('3.所定フォルダから今回利用するファイルを選ぶ')],
    [sg.Text('低圧用')],
    [sg.Input(), sg.FileBrowse(initial_folder=DEFAULT_FOL_1, key='-LV-')],
    [sg.Text('高圧用')],
    [sg.Input(), sg.FileBrowse(initial_folder=DEFAULT_FOL_2, key='-HV-')],
    [sg.Button('選択したらクリック', key='-selected_default_files-') ],
    [sg.HSep()],
    [sg.Text('4.ファイル名をチェックする'), sg.Button('Check_File_Name')],
    [sg.Text('チェック結果:'), sg.Text(size=(10,1), key='-check_result-')],
    [sg.HSep()],
    [sg.Text('5.作業フォルダにファイルをコピー'), sg.Button('Copy_To_WD')],
    [sg.HSep()],
    [sg.Text('6.申請書を作成する', font="default 12 bold", text_color='red', background_color="yellow"), sg.Button('Prepare_Application_Form', key="-form-")],
    [sg.Text('アウトプット:'),],
    [sg.Text(auto_size_text=True, key='-output_1-')],
    [sg.HSep()],
    [sg.Text('7.アウトプットを格納 or Wチェックを行う'), sg.Button('既定の格納場所を開く', key='-save_folder-')],
    [sg.HSep()],
    [sg.Button('Exit'), sg.Button('Cancel'), sg.Push(), sg.Text("経過時間:"), sg.Text("", size=(5,1), key='-duration-')],
]

current_time = 0
start_time = time_as_int()

window = sg.Window('FIT交付金申請', layout)

while True:
        
    # timeout毎にリフレッシュ(経過時間表示のためパラ追加)
    event, values = window.read(timeout=10)
    current_time = time_as_int() - start_time

    if event in (sg.WIN_CLOSED, 'Exit', 'Cancel'):
        break
    elif event == 'Open_Url':
        webbrowser.open(MANUAL_URL)
    elif event == 'Set_YYMM':
        houkoku_month = values['-報告月-']
        kyoukyu_month = get_ym(houkoku_month)
        window['-供給月-'].update(kyoukyu_month)
    elif event == 'New_Folder':
        work_folder_p = make_work_folder(values['-報告月-'])
        window['-new_folder_p-'].update(work_folder_p)
    elif event == '-selected_default_files-':
        default_file_LV = values["-LV-"].replace('/', '\\')
        default_file_HV = values["-HV-"].replace('/', '\\')
        default_file_LV_name = Path(default_file_LV).name
        default_file_HV_name = Path(default_file_HV).name
        print(f'{default_file_LV_name=}\n{default_file_HV_name=}')
    elif event == 'Check_File_Name':
        bool_1 = check_filename(default_file_LV_name, DEFAULT_FILENAME_KW_1)
        bool_2 = check_filename(default_file_HV_name, DEFAULT_FILENAME_KW_2)
        if all([bool_1, bool_2]):
            window["-check_result-"].update("OK")
        else:
            window["-check_result-"].update("NG")
            sg.popup_error("選択されたファイル名が違ってます。正しく選択してください。")
    elif event == 'Copy_To_WD':
        try:
            overwrite = sg.popup_ok_cancel("フォルダ内に同名ファイルがある場合は上書きされます。よろしいですか?")
            print(f'{overwrite=}')
            if overwrite == 'Cancel':
                sg.popup('処理を中断します')
                sys.exit()
            copy_to_folder(default_file_LV, work_folder_p)
            copy_to_folder(default_file_HV, work_folder_p)
            sg.popup("作業フォルダにコピーしました")
        except Exception as ex:
            sg.popup_error_with_traceback("処理を中断します")
            sys.exit()
    elif event == '-form-':
        output = f'output_{houkoku_month}報告{kyoukyu_month}買取.csv'
        output_p = work_folder_p / output
        shutil.copy(default_file_LV, output_p)
        window['-output_1-'].update(output_p)
        sg.popup("申請書を作成しました(仮)\n作業フォルダを開きます")
        sg.execute_command_subprocess('explorer', str(work_folder_p))
        sg.popup("作成されたデータを確認してください。\n\n問題なければ格納またはWチェックを行ってください")
    elif event == '-save_folder-':
        sg.execute_command_subprocess('explorer', OUTPUT_FOL)

    window['-duration-'].update('{:02d}:{:02d}'.format((current_time // 100) // 60, (current_time // 100) % 60))

window.close()