Merge commit '2408460f2924fa9ef6cae0094c67a153b663f181' into feature-NEWDWH2021-1173

This commit is contained in:
野間 2023-08-04 17:26:03 +09:00
commit 7773885220
76 changed files with 817 additions and 675 deletions

View File

@ -1,6 +1,7 @@
import gzip
import os
import os.path as path
import tarfile
import shutil
import tempfile
import boto3
@ -134,14 +135,14 @@ class VjskReceiveBucket(S3Bucket):
return temporary_file_path
def unzip_data_file(self, filename: str):
ret = []
with tarfile.open(filename) as tar:
temp_dir = os.path.dirname(filename)
tar.extractall(path=temp_dir)
extracted_files = tar.getnames()
for extracted_file in extracted_files:
file = os.path.join(temp_dir, extracted_file)
ret.append(file)
temp_dir = os.path.dirname(filename)
decompress_filename = os.path.basename(filename).replace('.gz', '')
decompress_file_path = os.path.join(temp_dir, decompress_filename)
with gzip.open(filename, 'rb') as gz:
with open(decompress_file_path, 'wb') as decompressed_file:
shutil.copyfileobj(gz, decompressed_file)
ret = [decompress_file_path]
return ret
def backup_dat_file(self, target_files: list, datetime_key: str):

View File

@ -60,6 +60,7 @@ def update_batch_processing_flag_in_processing() -> None:
"""
try:
db.connect()
db.to_jst()
db.execute(sql, {'in_processing': constants.BATCH_ACTF_BATCH_IN_PROCESSING})
except DBException as e:
raise BatchOperationException(e)
@ -87,6 +88,7 @@ def update_batch_process_complete() -> None:
"""
try:
db.connect()
db.to_jst()
db.execute(sql, {
'batch_complete': constants.BATCH_ACTF_BATCH_UNPROCESSED,
'dump_unprocessed': constants.DUMP_STATUS_KBN_UNPROCESSED

View File

@ -20,6 +20,7 @@ def exec():
db = Database.get_instance()
try:
db.connect()
db.to_jst()
db.begin()
logger.debug('DCF施設統合マスタ作成処理開始')
# COM施設からDCF施設統合マスタに登録

View File

@ -14,6 +14,7 @@ def exec():
db = Database.get_instance()
try:
db.connect()
db.to_jst()
db.begin()
logger.debug('DCF施設統合マスタ日次更新処理開始')
# DCF施設統合マスタ移行先コードのセット(無効フラグが『0(有効)』)

View File

@ -13,6 +13,7 @@ def exec():
db = Database.get_instance()
try:
db.connect()
db.to_jst()
logger.debug('##########################')
logger.debug('START Changing Employee in charge of institution PGM.')
# `emp_chg_inst_lau`をTruncate

View File

@ -11,6 +11,7 @@ def exec():
db = Database.get_instance(autocommit=True)
try:
db.connect()
db.to_jst()
logger.debug('処理開始')
# 卸販売実績テーブル(洗替後)過去5年以前のデータ削除
_call_sales_lau_delete(db)

View File

@ -13,6 +13,7 @@ def exec():
db = Database.get_instance()
try:
db.connect()
db.to_jst()
logger.debug('納入先処方元マスタの洗替処理開始')
# ult_ident_presc_lauをTruncate
_truncate_ult_ident_presc_lau(db)

View File

@ -37,6 +37,7 @@ class VjskDataLoadManager:
try:
# データベース接続
db.connect()
db.to_jst()
db.execute("SET SESSION sql_mode = 'TRADITIONAL';")
# orgをtruncate

View File

@ -333,7 +333,7 @@ class VjskReceiveFileMapper:
,t.dsp_odr
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.hld_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -347,7 +347,7 @@ class VjskReceiveFileMapper:
,dsp_odr=t.dsp_odr
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,dwh_upd_dt=SYSDATE()
;
""")
@ -397,7 +397,7 @@ class VjskReceiveFileMapper:
,t.dsp_odr
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.whs_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -416,7 +416,7 @@ class VjskReceiveFileMapper:
,dsp_odr=t.dsp_odr
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -526,7 +526,7 @@ class VjskReceiveFileMapper:
,t.end_date
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.mkr_org_horizon_v AS t
ON DUPLICATE KEY UPDATE
@ -575,7 +575,7 @@ class VjskReceiveFileMapper:
,end_date=t.end_date
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -615,7 +615,7 @@ class VjskReceiveFileMapper:
,t.dsp_odr
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.org_cnv_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -629,7 +629,7 @@ class VjskReceiveFileMapper:
,dsp_odr=t.dsp_odr
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -665,7 +665,7 @@ class VjskReceiveFileMapper:
,t.dsp_odr
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.tran_kbn_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -677,7 +677,7 @@ class VjskReceiveFileMapper:
,dsp_odr=t.dsp_odr
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -743,7 +743,7 @@ class VjskReceiveFileMapper:
,t.fcl_type
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.fcl_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -770,7 +770,7 @@ class VjskReceiveFileMapper:
,fcl_type=t.fcl_type
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -844,7 +844,7 @@ class VjskReceiveFileMapper:
,t.dsp_odr
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.phm_prd_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -875,7 +875,7 @@ class VjskReceiveFileMapper:
,dsp_odr=t.dsp_odr
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -913,7 +913,7 @@ class VjskReceiveFileMapper:
,t.dsp_odr
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.phm_price_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -926,7 +926,7 @@ class VjskReceiveFileMapper:
,dsp_odr=t.dsp_odr
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -1011,7 +1011,7 @@ class VjskReceiveFileMapper:
,t.tel_num
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.whs_customer_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -1031,7 +1031,7 @@ class VjskReceiveFileMapper:
,tel_num=t.tel_num
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")
@ -1065,7 +1065,7 @@ class VjskReceiveFileMapper:
,t.start_date
,t.rec_sts_kbn
,nullif(t.ins_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,t.upd_dt
,nullif(t.upd_dt, 0) -- 受領データがブランクだった場合にゼロ日付で取得されるので明示的にNULL値に変換する
,SYSDATE()
FROM org05.mdb_cnv_mst_v AS t
ON DUPLICATE KEY UPDATE
@ -1076,7 +1076,7 @@ class VjskReceiveFileMapper:
,start_date=t.start_date
,rec_sts_kbn=t.rec_sts_kbn
,ins_dt=nullif(t.ins_dt, 0)
,upd_dt=t.upd_dt
,upd_dt=nullif(t.upd_dt, 0)
,dwh_upd_dt=SYSDATE()
;
""")

View File

@ -180,6 +180,9 @@ class Database:
self.__connection.close()
self.__connection = None
def to_jst(self):
self.execute('SET time_zone = "+9:00"')
def __execute_with_transaction(self, query: str, parameters: dict):
# トランザクションを開始してクエリを実行する
with self.__connection.begin():

View File

@ -39,6 +39,7 @@ class TestImportFileToDb:
self.db = database
self.db.connect()
self.db.execute("set sql_mode = 'TRADITIONAL';")
self.db.to_jst()
# self.db.begin()
# testing
@ -1159,7 +1160,7 @@ class TestImportFileToDb:
_import_file_to_db(received_s3_files)
# 検証
assert str(e.value) == "file could not be opened successfully"
assert str(e.value) == "Not a gzipped file (b'7z')"
# teardown
for test_file in test_files:

View File

@ -12,6 +12,7 @@ def exec():
db = Database.get_instance()
try:
db.connect()
db.to_jst()
logger.debug('処理開始')
# 卸販売実績テーブル(洗替後)作成
_call_sales_lau_upsert(db)

View File

@ -1,10 +1,11 @@
from sqlalchemy import (Connection, CursorResult, Engine, QueuePool,
create_engine, text)
from sqlalchemy.engine.url import URL
from tenacity import retry, stop_after_attempt, wait_exponential
from src.error.exceptions import DBException
from src.logging.get_logger import get_logger
from src.system_var import environment
from tenacity import retry, stop_after_attempt, wait_exponential
logger = get_logger(__name__)
@ -12,15 +13,17 @@ logger = get_logger(__name__)
class Database:
"""データベース操作クラス"""
__connection: Connection = None
__engine: Engine = None
__transactional_engine: Engine = None
__autocommit_engine: Engine = None
__host: str = None
__port: str = None
__username: str = None
__password: str = None
__schema: str = None
__autocommit: bool = None
__connection_string: str = None
def __init__(self, username: str, password: str, host: str, port: int, schema: str) -> None:
def __init__(self, username: str, password: str, host: str, port: int, schema: str, autocommit: bool = False) -> None:
"""このクラスの新たなインスタンスを初期化します
Args:
@ -29,12 +32,14 @@ class Database:
host (str): DBホスト名
port (int): DBポート
schema (str): DBスキーマ名
autocommit(bool): 自動コミットモードで接続するかどうか(Trueの場合トランザクションの有無に限らず即座にコミットされる). Defaults to False.
"""
self.__username = username
self.__password = password
self.__host = host
self.__port = int(port)
self.__schema = schema
self.__autocommit = autocommit
self.__connection_string = URL.create(
drivername='mysql+pymysql',
@ -43,19 +48,23 @@ class Database:
host=self.__host,
port=self.__port,
database=self.__schema,
query={"charset": "utf8mb4"}
query={"charset": "utf8mb4", "local_infile": "1"},
)
self.__engine = create_engine(
self.__transactional_engine = create_engine(
self.__connection_string,
pool_timeout=5,
poolclass=QueuePool
)
self.__autocommit_engine = self.__transactional_engine.execution_options(isolation_level='AUTOCOMMIT')
@classmethod
def get_instance(cls):
def get_instance(cls, autocommit=False):
"""インスタンスを取得します
Args:
autocommit (bool, optional): 自動コミットモードで接続するかどうか(Trueの場合トランザクションの有無に限らず即座にコミットされる). Defaults to False.
Returns:
Database: DB操作クラスインスタンス
"""
@ -64,7 +73,8 @@ class Database:
password=environment.DB_PASSWORD,
host=environment.DB_HOST,
port=environment.DB_PORT,
schema=environment.DB_SCHEMA
schema=environment.DB_SCHEMA,
autocommit=autocommit
)
@retry(
@ -75,15 +85,18 @@ class Database:
),
stop=stop_after_attempt(environment.DB_CONNECTION_MAX_RETRY_ATTEMPT),
retry_error_cls=DBException
)
)
def connect(self):
"""
DBに接続します接続に失敗した場合リトライします
DBに接続します接続に失敗した場合リトライします\n
インスタンスのautocommitがTrueの場合自動コミットモードで接続する明示的なトランザクションも無視される
Raises:
DBException: 接続失敗
"""
try:
self.__connection = self.__engine.connect()
self.__connection = (
self.__autocommit_engine.connect() if self.__autocommit is True
else self.__transactional_engine.connect())
except Exception as e:
raise DBException(e)
@ -167,6 +180,9 @@ class Database:
self.__connection.close()
self.__connection = None
def to_jst(self):
self.execute('SET time_zone = "+9:00"')
def __execute_with_transaction(self, query: str, parameters: dict):
# トランザクションを開始してクエリを実行する
with self.__connection.begin():

View File

@ -30,6 +30,8 @@ def exec():
except Exception as e:
logger.info('DB接続エラーです')
raise e
# タイムゾーンをJSTに変更
db.to_jst()
# トランザクションの開始
db.begin()

View File

@ -167,6 +167,9 @@ class Database:
self.__connection.close()
self.__connection = None
def to_jst(self):
self.execute('SET time_zone = "+9:00"')
def __execute_with_transaction(self, query: str, parameters: dict):
# トランザクションを開始してクエリを実行する
with self.__connection.begin():

View File

@ -1,4 +1,4 @@
FROM python:3.9
FROM python:3.9-bullseye
ENV TZ="Asia/Tokyo"

View File

@ -55,6 +55,7 @@ def update_dump_status_kbn_in_processing() -> None:
"""
try:
db.connect()
db.to_jst()
db.execute(sql, {'in_processing': constants.BATCH_ACTF_BATCH_IN_PROCESSING})
except DBException as e:
raise BatchOperationException(e)
@ -80,6 +81,7 @@ def update_dump_status_kbn_error() -> None:
"""
try:
db.connect()
db.to_jst()
db.execute(sql, {
'dump_unprocessed': constants.DUMP_STATUS_KBN_ERROR
})
@ -107,6 +109,7 @@ def update_dump_status_kbn_complete() -> None:
"""
try:
db.connect()
db.to_jst()
db.execute(sql, {
'dump_unprocessed': constants.DUMP_STATUS_KBN_COMPLETE
})

View File

@ -165,6 +165,9 @@ class Database:
self.__connection.close()
self.__connection = None
def to_jst(self):
self.execute('SET time_zone = "+9:00"')
def __execute_with_transaction(self, query: str, parameters: dict):
# トランザクションを開始してクエリを実行する
with self.__connection.begin():

View File

@ -23,8 +23,7 @@ def exec():
# 日次バッチ処置中フラグ、dump処理状態区分を取得
batch_processing_flag, dump_status_kbn = get_batch_statuses()
except BatchOperationException as e:
logger.exception(f'日付テーブル取得エラー(異常終了):{e}')
return constants.BATCH_EXIT_CODE_SUCCESS
raise BatchOperationException(f'日付テーブル取得エラー(異常終了):{e}')
# 日次バッチ処理中の場合、処理は行わない
if batch_processing_flag == constants.BATCH_ACTF_BATCH_IN_PROCESSING:
@ -45,8 +44,7 @@ def exec():
try:
update_dump_status_kbn_in_processing()
except BatchOperationException as e:
logger.exception(f'dump処理状態区分更新(未処理→処理中) エラー(異常終了):{e}')
return constants.BATCH_EXIT_CODE_SUCCESS
raise BatchOperationException(f'dump処理状態区分更新(未処理→処理中) エラー(異常終了):{e}')
# MySQL接続情報を作成する
my_cnf_file_content = f"""
@ -93,25 +91,21 @@ def exec():
# パイプラインを実行し、エラーハンドリング
_, error = mysqldump_process.communicate()
if mysqldump_process.returncode != 0:
logger.error(f'`mysqldump`実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
return constants.BATCH_EXIT_CODE_SUCCESS
raise BatchOperationException(f'`mysqldump`実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
_, error = gzip_process.communicate()
if gzip_process.returncode != 0:
logger.error(f'`gzip`実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
return constants.BATCH_EXIT_CODE_SUCCESS
raise BatchOperationException(f'`gzip`実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
_, error = s3_cp_process.communicate()
if s3_cp_process.returncode != 0:
logger.error(f'`aws s3 cp`実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
return constants.BATCH_EXIT_CODE_SUCCESS
raise BatchOperationException(f'`aws s3 cp`実行時にエラーが発生しました。{"" if error is None else error.decode("utf-8")}')
# dump処理状態区分を正常終了に更新
try:
update_dump_status_kbn_complete()
except BatchOperationException as e:
logger.exception(f'dump処理状態区分更新(処理中→正常終了) エラー(異常終了):{e}')
return constants.BATCH_EXIT_CODE_SUCCESS
raise BatchOperationException(f'dump処理状態区分更新(処理中→正常終了) エラー(異常終了):{e}')
logger.info('日次バッチ処理前DBダンプ取得終了正常終了')
logger.info(f'出力ファイルパス: {s3_file_path}')

View File

@ -1,4 +1,4 @@
FROM python:3.9
FROM python:3.9-bullseye
ENV TZ="Asia/Tokyo"

View File

@ -7,7 +7,8 @@ name = "pypi"
app = "uvicorn src.main:app --reload --no-server-header"
[packages]
fastapi = "*"
fastapi = "==0.*"
pydantic = "==2.*"
uvicorn = "*"
"uvicorn[standard]" = "*"
gunicorn = "*"
@ -22,7 +23,7 @@ PyMySQL = "*"
pandas = "*"
openpyxl = "*"
xlrd = "*"
sqlalchemy = "*"
sqlalchemy = "==2.*"
mojimoji = "*"
[dev-packages]

File diff suppressed because it is too large Load Diff

View File

@ -28,14 +28,16 @@ def logout_view(
redirect_to = '/login/userlogin'
link_text = 'MeDaCA機能メニューへ'
# セッションが切れておらず、メンテユーザである、またはメンテログイン画面から遷移した場合、メンテログイン画面に戻す
if (session is not None and session.user_flg == '1') or referer.endswith('maintlogin'):
if (session is not None and session.user_flg == str(constants.PERMISSION_ENABLED)) \
or referer.endswith('maintlogin'):
redirect_to = '/login/maintlogin'
link_text = 'Login画面に戻る'
logout = LogoutViewModel()
logout.redirect_to = redirect_to
logout.reason = constants.LOGOUT_REASON_MESSAGE_MAP.get(reason, '')
logout.link_text = link_text
logout = LogoutViewModel(
redirect_to=redirect_to,
reason=constants.LOGOUT_REASON_MESSAGE_MAP.get(reason, ''),
link_text=link_text
)
template_response = templates.TemplateResponse(
'logout.html',
{

View File

@ -42,7 +42,7 @@ def menu_view(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる
@ -82,7 +82,7 @@ def inst_emp_csv_upload_view(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる
@ -124,7 +124,7 @@ async def inst_emp_csv_upload(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる
@ -186,7 +186,7 @@ def new_inst_result_view(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる
@ -226,7 +226,7 @@ def inst_emp_csv_download_view(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる
@ -270,7 +270,7 @@ async def inst_emp_csv_download(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる
@ -338,7 +338,7 @@ def table_override_view(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる
@ -379,7 +379,7 @@ def table_override_result_view(
session: UserSession = request.session
# マスタメンテメニューへのアクセス権がない場合、ログアウトさせる
if session.master_mainte_flg != '1':
if session.master_mainte_flg == constants.PERMISSION_DISABLED:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
# バッチ処理中の場合、ログアウトさせる

View File

@ -180,6 +180,9 @@ class Database:
self.__connection.close()
self.__connection = None
def to_jst(self):
self.execute('SET time_zone = "+9:00"')
def __execute_with_transaction(self, query: str, parameters: dict):
# トランザクションを開始してクエリを実行する
with self.__connection.begin():

View File

@ -6,7 +6,6 @@ from src.model.db.base_db_model import BaseDBModel
class BioSalesLotDBModel(BaseDBModel):
slip_mgt_num: Optional[str]
conv_cd: Optional[int]
rec_whs_cd: Optional[str]
rec_whs_sub_cd: Optional[str]
rec_whs_org_cd: Optional[str]
@ -14,39 +13,27 @@ class BioSalesLotDBModel(BaseDBModel):
rec_tran_kbn: Optional[str]
rev_hsdnymd_srk: Optional[str]
rec_urag_num: Optional[str]
rec_comm_name: Optional[str]
rec_nonyu_fcl_name: Optional[str]
rec_nonyu_fcl_addr: Optional[str]
rec_lot_num: Optional[str]
rec_ymd: Optional[str]
v_tran_cd: Optional[int]
tran_kbn_name: Optional[str]
whs_org_cd: Optional[str]
v_whsorg_cd: Optional[int]
whs_org_name: Optional[str]
v_whs_cd: Optional[int]
whs_name: Optional[str]
nonyu_fcl_cd: Optional[str]
v_inst_cd: Optional[str]
v_inst_kn: Optional[str]
v_inst_name: Optional[str]
v_inst_addr: Optional[str]
comm_cd: Optional[str]
product_name: Optional[str]
whs_rep_comm_name: Optional[str]
whs_rep_nonyu_fcl_name: Optional[str]
whs_rep_nonyu_fcl_addr: Optional[str]
mkr_inf_1: Optional[str]
mkr_cd: Optional[str]
qty: Optional[int]
slip_org_kbn: Optional[str]
bef_slip_mgt_num: Optional[str]
lot_no_err_flg: Optional[str]
iko_flg: Optional[str]
rec_sts_kbn: Optional[str]
ins_dt: Optional[datetime]
ins_usr: Optional[str]
dwh_upd_dt: Optional[datetime]
inst_cd: Optional[str]
inst_name_form: Optional[str]
address: Optional[str]

View File

@ -1,4 +1,3 @@
from datetime import date
from typing import Optional
from src.model.db.base_db_model import BaseDBModel
@ -10,5 +9,5 @@ class UltmarcDoctorWrkplaceHisDBModel(BaseDBModel):
blng_sec_name: Optional[str]
univ_post_name: Optional[str]
post_name: Optional[str]
aply_start_ymd: Optional[date]
aply_end_ymd: Optional[date]
aply_start_ymd: Optional[str]
aply_end_ymd: Optional[str]

View File

@ -34,15 +34,15 @@ class UltmarcInstInfoDBModel(BaseDBModel):
insp_item_paras: Optional[str]
insp_item_biochem: Optional[str]
insp_item_ri: Optional[str]
prmit_bed_num_gen: Optional[str]
prmit_bed_num_rcup: Optional[str]
prmit_bed_num_mental: Optional[str]
prmit_bed_num_infection: Optional[str]
prmit_bed_num_tuber: Optional[str]
prmit_bed_num_other: Optional[str]
prmit_bed_num_sum: Optional[str]
prmit_bed_num_gen: Optional[int]
prmit_bed_num_rcup: Optional[int]
prmit_bed_num_mental: Optional[int]
prmit_bed_num_infection: Optional[int]
prmit_bed_num_tuber: Optional[int]
prmit_bed_num_other: Optional[int]
prmit_bed_num_sum: Optional[int]
ward_abolish_flg: Optional[str]
bed_num: Optional[str]
bed_num: Optional[int]
prmit_bed_maint_ymd: Optional[str]
inst_repre_cd: Optional[str]
inst_repre_kana: Optional[str]

View File

@ -7,17 +7,17 @@ from src.model.db.base_db_model import BaseDBModel
class UserMasterModel(BaseDBModel):
user_id: Optional[str]
mail_adr: Optional[str]
user_nm: Optional[str]
auth_flg1: Optional[str]
auth_flg2: Optional[str]
auth_flg3: Optional[str]
auth_flg4: Optional[str]
auth_flg5: Optional[str]
auth_flg6: Optional[str]
auth_flg7: Optional[str]
auth_flg8: Optional[str]
auth_flg9: Optional[str]
auth_flg10: Optional[str]
user_name: Optional[str]
auth_flg1: Optional[int]
auth_flg2: Optional[int]
auth_flg3: Optional[int]
auth_flg4: Optional[int]
auth_flg5: Optional[int]
auth_flg6: Optional[int]
auth_flg7: Optional[int]
auth_flg8: Optional[int]
auth_flg9: Optional[int]
auth_flg10: Optional[int]
pwd: Optional[str]
enabled_flg: Optional[str]
creater: Optional[str]

View File

@ -30,6 +30,7 @@ class MasterMainteEmpChgInstFunction(metaclass=ABCMeta):
error_list = []
try:
self.emp_chginst_repository.connect()
self.emp_chginst_repository.to_jst()
self.emp_chginst_repository.begin()
(result_message, error_list) = self.write_emp_chg_inst_table()
if len(error_list) > 0:

View File

@ -14,10 +14,10 @@ class UserSession(DynamoDBTableModel):
session_key = UnicodeAttribute(hash_key=True)
user_id = UnicodeAttribute()
id_token = UnicodeAttribute()
doc_flg = UnicodeAttribute(null=True)
inst_flg = UnicodeAttribute(null=True)
bio_flg = UnicodeAttribute(null=True)
master_mainte_flg = UnicodeAttribute(null=True)
doc_flg = NumberAttribute(null=True)
inst_flg = NumberAttribute(null=True)
bio_flg = NumberAttribute(null=True)
master_mainte_flg = NumberAttribute(null=True)
user_flg = UnicodeAttribute(null=True)
refresh_token = UnicodeAttribute()
csrf_token = UnicodeAttribute()

View File

@ -14,7 +14,7 @@ class RequestBaseModel(BaseModel):
"""
def unescape(self):
for k, v in self.dict().items():
for k, v in self.model_dump().items():
if v is not None and type(v) is str:
setattr(self, k, html.unescape(v))
return self

View File

@ -47,7 +47,7 @@ class UltmarcInstSearchModel(RequestBaseModel):
)
def unescape(self):
for k, v in self.dict().items():
for k, v in self.model_dump().items():
if v is not None and type(v) is str:
setattr(self, k, html.unescape(v))
return self

View File

@ -5,4 +5,4 @@ from src.util.sanitize import sanitize
@sanitize
class BisDisplayModel(BioSalesLotDBModel):
def __init__(self, param: BioSalesLotDBModel) -> None:
super().__init__(**param.dict())
super().__init__(**param.model_dump())

View File

@ -14,12 +14,11 @@ from src.system_var import environment
class BioViewModel(BaseModel):
subtitle: str = '生物由来検索一覧'
user_id: Optional[str]
batch_status: Optional[str]
user_id: str
whs_models: list[WholesalerMasterModel]
phm_models: list[PharmacyProductMasterModel]
bio_data: Optional[list[BisDisplayModel]] = []
form_data: Optional[BioModel]
bio_data: Optional[list[BisDisplayModel]] = None
form_data: BioModel = None
def display_wholesaler_names(self):
display_names = [
@ -56,7 +55,7 @@ class BioViewModel(BaseModel):
"""json.dumpsの日付項目のフォーマットハンドラ"""
return obj.isoformat().replace('T', ' ') if hasattr(obj, 'isoformat') else obj
search_data_list = [model.dict() for model in self.bio_data]
search_data_list = [model.model_dump() for model in self.bio_data]
search_data_len = len(search_data_list)
# 呼び出し一回あたりの分割数
part_size = 500
@ -147,10 +146,10 @@ class BioViewModel(BaseModel):
return self.form_data is not None
def is_data_empty(self):
return len(self.bio_data) == 0
return self.bio_data is None or len(self.bio_data) == 0
def is_data_overflow_max_length(self):
return len(self.bio_data) > environment.BIO_SEARCH_RESULT_MAX_COUNT
return self.bio_data is None or len(self.bio_data) > environment.BIO_SEARCH_RESULT_MAX_COUNT
def _format_date_string(self, date_string):
if date_string is None:

View File

@ -1,28 +1,28 @@
from pydantic import BaseModel
from typing import Optional
from src.util.string_util import is_not_empty
class InstEmpCsvDownloadViewModel(BaseModel):
subtitle: str = '施設担当者データCSVダウンロード'
is_search: Optional[bool] = False
ta_cd: Optional[str] = ''
inst_cd: Optional[str] = ''
emp_cd: Optional[str] = ''
apply_date_from: Optional[str] = ''
start_date_from: Optional[str] = ''
start_date_to: Optional[str] = ''
end_date_from: Optional[str] = ''
end_date_to: Optional[str] = ''
create_date_from: Optional[str] = ''
create_date_to: Optional[str] = ''
update_date_from: Optional[str] = ''
update_date_to: Optional[str] = ''
select_table: Optional[str] = ''
data_count: Optional[int] = 0
result_msg: Optional[str] = ''
download_file_url: Optional[str] = ''
file_name: Optional[str] = ''
is_search: bool = False
ta_cd: str = ''
inst_cd: str = ''
emp_cd: str = ''
apply_date_from: str = ''
start_date_from: str = ''
start_date_to: str = ''
end_date_from: str = ''
end_date_to: str = ''
create_date_from: str = ''
create_date_to: str = ''
update_date_from: str = ''
update_date_to: str = ''
select_table: str = ''
data_count: int = 0
result_msg: str = ''
download_file_url: str = ''
file_name: str = ''
def is_select_table_empty(self):
return not is_not_empty(self.select_table)

View File

@ -1,21 +1,20 @@
from typing import Optional
from pydantic import BaseModel
from src.system_var import constants
class InstEmpCsvUploadViewModel(BaseModel):
subtitle: str = '施設担当者データCSVアップロード'
is_verified: Optional[bool]
is_insert: Optional[bool]
error_message_list: Optional[list[str]]
select_function: Optional[str]
select_table: Optional[str]
csv_file_name: Optional[str]
csv_upload_list: Optional[list[dict]]
json_upload_data: Optional[str]
result_message_list: Optional[list[str]]
select_function_message: Optional[str]
is_verified: bool = False
is_insert: bool = False
error_message_list: list[str] = None
select_function: str = None
select_table: str = None
csv_file_name: str = None
csv_upload_list: list[dict] = None
json_upload_data: str = None
result_message_list: list[str] = None
select_function_message: str = None
def select_table_message(self):
return self.__dummy_table() if self.select_table == 'dummy' else self.__real_table()

View File

@ -1,10 +1,8 @@
from typing import Optional
from pydantic import BaseModel
class LogoutViewModel(BaseModel):
subtitle: str = 'MeDaCA Logout'
redirect_to: Optional[str]
reason: Optional[str]
link_text: Optional[str]
redirect_to: str
reason: str
link_text: str

View File

@ -1,5 +1,3 @@
from typing import Optional
from pydantic import BaseModel
from src.model.view.user_view_model import UserViewModel
@ -8,8 +6,8 @@ from src.system_var import constants
class MenuViewModel(BaseModel):
subtitle: str = 'MeDaCA 機能メニュー'
batch_status: Optional[str]
dump_status: Optional[str]
batch_status: str
dump_status: str
user_model: UserViewModel
def is_batch_processing(self):

View File

@ -1,8 +1,7 @@
from pydantic import BaseModel
from typing import Optional
class TableOverrideViewModel(BaseModel):
subtitle: str = 'テーブル上書きコピー'
is_override: Optional[bool] = False
is_override: bool = False

View File

@ -16,16 +16,16 @@ from src.system_var import environment
class UltmarcDoctorInfoViewModel(BaseModel):
subtitle: str = '医師情報'
is_batch_processing: Optional[bool]
doctor_info_data: Optional[UltmarcDoctorInfoDBModel]
trt_coursed_data: Optional[list[UltmarcDrTrtCourseDBModel]]
sosiety_data: Optional[list[UltmarcSosietyDBModel]]
specialist_license_data: Optional[list[UltmarcSpecialistLicenseDBModel]]
doctor_wrkplace_data: Optional[list[UltmarcDoctorWrkplaceDBModel]]
doctor_wrkplace_his_data: Optional[list[UltmarcDoctorWrkplaceHisDBModel]]
doc_id: Optional[str]
post_cnt: Optional[int]
page_num: Optional[int]
is_batch_processing: bool = None
doctor_info_data: UltmarcDoctorInfoDBModel = None
trt_coursed_data: Optional[list[UltmarcDrTrtCourseDBModel]] = None
sosiety_data: Optional[list[UltmarcSosietyDBModel]] = None
specialist_license_data: Optional[list[UltmarcSpecialistLicenseDBModel]] = None
doctor_wrkplace_data: Optional[list[UltmarcDoctorWrkplaceDBModel]] = None
doctor_wrkplace_his_data: Optional[list[UltmarcDoctorWrkplaceHisDBModel]] = None
doc_id: str = None
post_cnt: int = None
page_num: int = None
# 現在のページ(表示用)
def is_page_num_view(self):
@ -52,16 +52,21 @@ class UltmarcDoctorInfoViewModel(BaseModel):
else:
return ''
def is_input_his_aply_start_ymd_format(self, date_string):
if date_string:
return self._format_date(date_string)
# 医師勤務先履歴_開始年月日
def is_input_his_aply_start_ymd_format(self, aply_start_date_string):
if aply_start_date_string:
# 医師勤務先履歴の適用開始年月日は文字列型なので、日付に変換してから渡す
aply_start_date = datetime.strptime(aply_start_date_string, '%Y%m%d')
return self._format_date(aply_start_date)
else:
return ''
# 終了年月日
def is_input_his_aply_end_ymd_format(self, date_string):
if date_string:
return self._format_date(date_string)
# 医師勤務先履歴_終了年月日
def is_input_his_aply_end_ymd_format(self, aply_end_date_string):
if aply_end_date_string:
# 医師勤務先履歴の適用開始年月日は文字列型なので、日付に変換してから渡す
aply_end_date = datetime.strptime(aply_end_date_string, '%Y%m%d')
return self._format_date(aply_end_date)
else:
return ''

View File

@ -11,10 +11,10 @@ from src.system_var import environment
class UltmarcDoctorSearchViewModel(BaseModel):
subtitle: str = '医師検索一覧'
is_batch_processing: Optional[bool]
is_batch_processing: bool = None
prefc_models: list[PrefcMasterModel]
doctor_data: Optional[list[UltmarcDoctorDBModel]] = []
form_data: Optional[UltmarcDoctorSearchModel]
doctor_data: Optional[list[UltmarcDoctorDBModel]] = None
form_data: UltmarcDoctorSearchModel = None
def ultmarc_data_json_str(self):
"""アルトマーク医師データの検索結果を指定された件数ごとに分割しながら返す"""
@ -22,7 +22,7 @@ class UltmarcDoctorSearchViewModel(BaseModel):
"""json.dumpsの日付項目のフォーマットハンドラ"""
return obj.isoformat() if hasattr(obj, 'isoformat') else obj
search_data_list = [model.dict() for model in self.doctor_data]
search_data_list = [model.model_dump() for model in self.doctor_data]
search_data_len = len(search_data_list)
# 呼び出し一回あたりの分割数
part_size = 50
@ -119,10 +119,10 @@ class UltmarcDoctorSearchViewModel(BaseModel):
return self.form_data is not None
def is_data_empty(self):
return len(self.doctor_data) == 0
return self.doctor_data is None or len(self.doctor_data) == 0
def is_data_overflow_max_length(self):
return len(self.doctor_data) > environment.ULTMARC_SEARCH_RESULT_MAX_COUNT
return self.doctor_data is not None and len(self.doctor_data) > environment.ULTMARC_SEARCH_RESULT_MAX_COUNT
def _selected_value(self, form_value: str, current_value: str):
return 'selected' if form_value == current_value else ''

View File

@ -9,13 +9,13 @@ from src.system_var import environment
class UltmarcInstInfoViewModel(BaseModel):
subtitle: str = '施設情報'
is_batch_processing: Optional[bool]
inst_info_data: Optional[UltmarcInstInfoDBModel]
inst_trt_coursed_data: Optional[list[UltmarcInstTrtCourseDBModel]]
doctor_wrkplace_count: Optional[int]
inst_id: Optional[str]
post_cnt: Optional[int]
page_num: Optional[int]
is_batch_processing: bool = None
inst_info_data: UltmarcInstInfoDBModel = None
inst_trt_coursed_data: Optional[list[UltmarcInstTrtCourseDBModel]] = None
doctor_wrkplace_count: int = None
inst_id: str = None
post_cnt: int = None
page_num: int = None
# 未確認
def is_checked_unconf_flg(self):

View File

@ -12,11 +12,11 @@ from src.system_var import environment
class UltmarcInstSearchViewModel(BaseModel):
subtitle: str = '施設検索一覧'
is_batch_processing: Optional[bool]
is_batch_processing: bool = None
prefc_models: list[PrefcMasterModel]
inst_div_models: list[InstDivMasterModel]
inst_data: Optional[list[UltmarcInstDBModel]] = []
form_data: Optional[UltmarcInstSearchModel]
inst_data: Optional[list[UltmarcInstDBModel]] = None
form_data: UltmarcInstSearchModel = None
def ultmarc_data_json_str(self):
"""アルトマーク施設データの検索結果を指定された件数ごとに分割しながら返す"""
@ -24,7 +24,7 @@ class UltmarcInstSearchViewModel(BaseModel):
"""json.dumpsの日付項目のフォーマットハンドラ"""
return obj.isoformat() if hasattr(obj, 'isoformat') else obj
search_data_list = [model.dict() for model in self.inst_data]
search_data_list = [model.model_dump() for model in self.inst_data]
search_data_len = len(search_data_list)
# 呼び出し一回あたりの分割数
part_size = 50
@ -119,10 +119,10 @@ class UltmarcInstSearchViewModel(BaseModel):
return self.form_data is not None
def is_data_empty(self):
return len(self.inst_data) == 0
return self.inst_data is None or len(self.inst_data) == 0
def is_data_overflow_max_length(self):
return len(self.inst_data) >= environment.ULTMARC_SEARCH_RESULT_MAX_COUNT
return self.inst_data is not None and len(self.inst_data) >= environment.ULTMARC_SEARCH_RESULT_MAX_COUNT
def _selected_value(self, form_value: str, current_value: str):
return 'selected' if form_value == current_value else ''

View File

@ -2,22 +2,23 @@ from typing import Optional
from pydantic import BaseModel
from src.system_var import constants
class UserViewModel(BaseModel):
bio_flg: Optional[str] # AUTH_FLG1
doc_flg: Optional[str] # AUTH_FLG2
inst_flg: Optional[str] # AUTH_FLG3
master_mainte_flg: Optional[str] # AUTH_FLG4
user_flg: Optional[str] # MNTUSER_FLG
bio_flg: Optional[int] # AUTH_FLG1
doc_flg: Optional[int] # AUTH_FLG2
inst_flg: Optional[int] # AUTH_FLG3
master_mainte_flg: Optional[int] # AUTH_FLG4
def has_ult_doctor_permission(self):
return self.doc_flg == '1'
return self.doc_flg == constants.PERMISSION_ENABLED
def has_ult_inst_permission(self):
return self.inst_flg == '1'
return self.inst_flg == constants.PERMISSION_ENABLED
def has_bio_permission(self):
return self.bio_flg == '1'
return self.bio_flg == constants.PERMISSION_ENABLED
def has_master_maintenance_permission(self):
return self.master_mainte_flg == '1'
return self.master_mainte_flg == constants.PERMISSION_ENABLED

View File

@ -32,7 +32,7 @@ class BaseRepository(metaclass=ABCMeta):
def _to_data_frame(self, query, parameter: BaseDBModel):
"""DBの取得結果をデータフレームに変換する"""
params = params = parameter.dict()
params = params = parameter.model_dump()
sql_query = pd.read_sql(
text(query),

View File

@ -68,7 +68,7 @@ class BioSalesLotRepository(BaseRepository):
where_clause = self.__build_condition(parameter)
query = self.FETCH_SQL.format(where_clause=where_clause)
logger.debug(f'SQL: {query}')
result = self._database.execute_select(query, parameter.dict())
result = self._database.execute_select(query, parameter.model_dump())
logger.debug(f'count= {len(result)}')
models = [BioSalesLotDBModel(**r) for r in result]
return models

View File

@ -13,6 +13,9 @@ class EmpChgInstRepository(BaseRepository):
def connect(self):
self._database.connect()
def to_jst(self):
self._database.to_jst()
def begin(self):
self._database.begin()
@ -110,7 +113,7 @@ class EmpChgInstRepository(BaseRepository):
SET
emp_cd = :emp_cd,
updater = :update_user_name,
update_date = now()
update_date = NOW()
where
inst_cd = :inst_cd
and ta_cd = :ta_cd

View File

@ -52,10 +52,10 @@ class UltmarcDoctorRepository(BaseRepository):
try:
self._database.connect()
# 文字列の検索を部分一致にするため、モデルをコピー。以降はこのコピーを使用する。
clone_parameter = UltmarcDoctorSearchModel(**parameter.dict())
clone_parameter = UltmarcDoctorSearchModel(**parameter.model_dump())
where_clause = self.__build_condition(clone_parameter)
query = self.FETCH_SQL.format(where_clause=where_clause)
result = self._database.execute_select(query, clone_parameter.dict())
result = self._database.execute_select(query, clone_parameter.model_dump())
models = [UltmarcDoctorDBModel(**r) for r in result]
return models

View File

@ -39,10 +39,10 @@ class UltmarcInstRepository(BaseRepository):
try:
self._database.connect()
# 文字列の検索を部分一致にするため、モデルをコピー。以降はこのコピーを使用する。
clone_parameter = UltmarcInstSearchModel(**parameter.dict())
clone_parameter = UltmarcInstSearchModel(**parameter.model_dump())
where_clause = self.__build_condition(clone_parameter)
query = self.FETCH_SQL.format(where_clause=where_clause)
result = self._database.execute_select(query, clone_parameter.dict())
result = self._database.execute_select(query, clone_parameter.model_dump())
models = [UltmarcInstDBModel(**r) for r in result]
return models

View File

@ -8,7 +8,7 @@ logger = get_logger('COM_施設診療科目取得')
class UltmarcInstTrtCourseRepository(BaseRepository):
FETCH_SQL = """\
SELECT trt_course_name_abb
SELECT com_trt_course.trt_course_name_abb
FROM src05.com_inst
JOIN src05.com_inst_trt_course ON com_inst.dcf_dsf_inst_cd = com_inst_trt_course.dcf_dsf_inst_cd
LEFT JOIN src05.com_trt_course ON com_inst_trt_course.trt_course_cd = com_trt_course.trt_course_cd

View File

@ -8,7 +8,7 @@ logger = get_logger('COM_医師診療科目取得')
class UltmarcDrTrtCourseRepository(BaseRepository):
FETCH_SQL = """\
SELECT trt_course_name
SELECT com_trt_course.trt_course_name
FROM src05.com_dr
LEFT JOIN src05.com_dr_trt_course ON com_dr.dcf_pcf_dr_cd = com_dr_trt_course.dcf_pcf_dr_cd
LEFT JOIN src05.com_trt_course ON com_dr_trt_course.trt_course_cd = com_trt_course.trt_course_cd

View File

@ -112,7 +112,7 @@ class BioViewService(BaseService):
logger.info(sql_message)
# 検索パラメータを1行ずつ書き出す
for param_key, param_value in parameters.dict().items():
for param_key, param_value in parameters.model_dump().items():
if param_value is None or len(param_value) == 0:
continue
parameter_message = f'ユーザーID: {user_id} Value: {param_key} = {param_value}\t{download_file_name}'

View File

@ -149,6 +149,7 @@ class MasterMainteService(BaseService):
def copy_data_real_to_dummy(self) -> TableOverrideViewModel:
try:
self.emp_chginst_repository.connect()
self.emp_chginst_repository.to_jst()
self.emp_chginst_repository.begin()
self.emp_chginst_repository.delete_dummy_table()
self.emp_chginst_repository.copy_real_to_dummy()

View File

@ -14,6 +14,7 @@ h1 {
margin-left: 2%;
margin-top: 0%;
margin-bottom: 0%;
font-weight: 700;
}
table{

View File

@ -1,5 +1,10 @@
import os.path as path
# 各画面の権限:有効時の値
PERMISSION_ENABLED = 1
# 各画面の権限:無効時の値
PERMISSION_DISABLED = 0
# 日付テーブル.バッチ処理ステータス:未処理
BATCH_STATUS_PROCESSING = '1'
# 日付テーブル.dump取得状態区分未処理

View File

@ -39,7 +39,6 @@
<div class="docButchMsg">日次バッチ処理中のため、データが正しく表示されない可能性があります</div>
{% endif %}
</td>
<td class="docHeaderTd docHeaderTdRight"><button class="docHeader_bt" onclick="backToMenu()">メニューへ</button></td>
</tr>
</table>

View File

@ -13,18 +13,18 @@
formBtDisabled();
// DatePickerを有効化
enableDatePicker();
{% if mainte_csv_dl.is_search and mainte_csv_dl.data_count > 0 and mainte_csv_dl.is_download_file_url_empty() is false %}
// {% if mainte_csv_dl.is_search and mainte_csv_dl.data_count > 0 and mainte_csv_dl.is_download_file_url_empty() is false %}
// CSV自動ダウンロード処理
var link_tag = document.createElement("a");
const link_tag = document.createElement("a");
link_tag.Target="_blank";
link_tag.id = "download_url_link";
link_tag.style.display = 'none';
link_tag.style.display = 'none';
link_tag.setAttribute("href", "{{mainte_csv_dl.download_file_url | safe}}");
link_tag.setAttribute("download", "{{mainte_csv_dl.file_name}}");
document.getElementById("notification").appendChild(link_tag);
document.getElementById("download_url_link").click();
document.getElementById("download_url_link").remove();
{% endif %}
// {% endif %}
};
function Form_Submit_Disp_Dialog(){
var msg = 'CSVファイルを出力しますか';
@ -33,8 +33,8 @@
document.getElementById("csvOutputMsg").style.display = "none";
} else {
return false;
}
}
}
}
</script>
</head>
@ -98,7 +98,7 @@
oninput="formBtDisabled()"
>
<input class="searchDateTextbox date_picker" type="text" name="ctrl_start_date_to" value="{{mainte_csv_dl.start_date_to | safe}}" maxlength='10'
<input class="searchDateTextbox date_picker" type="text" name="ctrl_start_date_to" value="{{mainte_csv_dl.start_date_to | safe}}" maxlength='10'
onchange="formBtDisabled()"
oninput="formBtDisabled()"
>
@ -111,7 +111,7 @@
oninput="formBtDisabled()"
>
<input class="searchDateTextbox date_picker" type="text" name="ctrl_end_date_to" value="{{mainte_csv_dl.end_date_to | safe}}" maxlength='10'
<input class="searchDateTextbox date_picker" type="text" name="ctrl_end_date_to" value="{{mainte_csv_dl.end_date_to | safe}}" maxlength='10'
onchange="formBtDisabled()"
oninput="formBtDisabled()"
>
@ -122,13 +122,13 @@
<!-- 対象テーブル -->
<td class="searchLabelTd">対象テーブル:</td>
<td class="searchInputTd">
<label>
<label>
<input type="radio" name="radio_select_table" value="dummy"
{{ "checked " if mainte_csv_dl.select_table == 'dummy' or mainte_csv_dl.is_select_table_empty() }}
>ダミーテーブル
</label>
<label>
<input type="radio" name="radio_select_table" value="real"
<input type="radio" name="radio_select_table" value="real"
{{ "checked " if mainte_csv_dl.select_table == 'real' }}
>本番テーブル
</label>

View File

@ -8,9 +8,9 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript">
window.onload = function(){
{% if mainte_csv_up.is_insert %}
// {% if mainte_csv_up.is_insert %}
sessionStorage.clear();
{% else %}
// {% else %}
if (sessionStorage["ctrl_select_function"]) {
var element = document.getElementById("upload_form");
if (sessionStorage["ctrl_select_function"] === "new") {
@ -29,7 +29,7 @@
element.real_table.checked = true;
}
}
{% endif %}
// {% endif %}
}
function Form_Submit(){
sessionStorage.clear();

View File

@ -4,7 +4,7 @@
{% with subtitle = table_override.subtitle %}
{% include '_header.html' %}
{% endwith %}
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link href="/static/css/masterMainte.css" rel="stylesheet" />
<script type="text/javascript">
@ -51,8 +51,8 @@
{% if table_override.is_override %}
<p>
<div id="overRided" class="csvOutputMessage">ダミー従業員担当施設マスタのデータを本番従業員担当施設マスタのデータで上書きしました</div>
</p>
{% endif %}
</p>
{% endif %}
<div id="loading" class="csvOutputMessage" style="display:none;">
<p>データ上書き中...<br>しばらくお待ち下さい。</p>
</div>

View File

@ -42,6 +42,7 @@ BEGIN
'【洗替】1.卸組織洗替② 開始'
);
SET SESSION optimizer_switch = 'derived_merge=off';
INSERT INTO
internal05.whs_customer_org_t (
whs_cd,