初めてのEC-CUBE

BTOBのECサイトを作る
EC-CUBE4

Q:反映されない
A:本番環境にFTPなどでTwigファイルをアップロードして入れ替えた場合、画面を反映させるにはTwigキャッシュを削除する必要があります。
コンテンツ管理>キャッシュ管理>キャッシュ削除

EC-CUBEでログイン必須にする設定手順(例:商品詳細ページ)
1. src/Eccube/DependencyInjection/EccubeExtension.php を編集

初期設定

        $accessControl = [
          ['path' => '^/%eccube_admin_route%/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
          ['path' => '^/%eccube_admin_route%/', 'roles' => 'ROLE_ADMIN'],
          ['path' => '^/mypage/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
          ['path' => '^/mypage/withdraw_complete', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
          ['path' => '^/mypage/change', 'roles' => 'IS_AUTHENTICATED_FULLY'],
          ['path' => '^/mypage/', 'roles' => 'ROLE_USER'],
        ];
        if ($forceSSL) {
            foreach ($accessControl as &$control) {
                $control['requires_channel'] = 'https';
            }
        }
$accessControl = [
    // 管理画面のログインは未ログインでもアクセス可能
    ['path' => '^/%eccube_admin_route%/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
    
    // 管理画面は管理者のみアクセス可能
    ['path' => '^/%eccube_admin_route%/', 'roles' => 'ROLE_ADMIN'],

    // 会員ログイン・登録ページは未ログインでもアクセス可能
    ['path' => '^/mypage/login', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
    ['path' => '^/entry', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],
    ['path' => '^/help', 'roles' => 'IS_AUTHENTICATED_ANONYMOUSLY'],

    // それ以外のページはログイン必須
    ['path' => '^/', 'roles' => 'ROLE_USER'],
];

会員登録フォームの項目を変更する手順
ファイルパス: src/Eccube/Form/Type/Front/EntryType.php

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', NameType::class, [
                'required' => true,
            ])
            ->add('kana', KanaType::class, [])
            ->add('company_name', TextType::class, [
                'required' => false,
                'constraints' => [
                    new Assert\Length([
                        'max' => $this->eccubeConfig['eccube_stext_len'],
                    ]),
                ],
            ])
            ->add('postal_code', PostalType::class)
            ->add('address', AddressType::class)
            ->add('phone_number', PhoneNumberType::class, [
                'required' => true,
            ])
            ->add('email', RepeatedEmailType::class)
            ->add('plain_password', RepeatedPasswordType::class)
            ->add('sex', SexType::class, [
                'required' => false,
            ])
            ->add('job', JobType::class, [
                'required' => false,
            ]);

        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $Customer = $event->getData();
            if ($Customer instanceof Customer && !$Customer->getId()) {
                $form = $event->getForm();

                $form->add('user_policy_check', CheckboxType::class, [
                        'required' => true,
                        'label' => null,
                        'mapped' => false,
                        'constraints' => [
                            new Assert\NotBlank(),
                        ],
                    ]);
            }
        }
        );

        $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
            $form = $event->getForm();
            /** @var Customer $Customer */
            $Customer = $event->getData();
            if ($Customer->getPlainPassword() != '' && $Customer->getPlainPassword() == $Customer->getEmail()) {
                $form['plain_password']['first']->addError(new FormError(trans('common.password_eq_email')));
            }
        });
    }



openpyxl基礎【python】

よく使うコードのメモ

from openpyxl import load_workbook

# Excelファイルを読み込み
wb = load_workbook("test.xlsx")
ws = wb.active

# 列幅を設定
ws.column_dimensions['A'].width = 20
ws.column_dimensions['B'].width = 20
ws.column_dimensions['C'].width = 5
ws.column_dimensions['D'].width = 30
ws.column_dimensions['E'].width = 30
ws.column_dimensions['F'].width = 20
ws.column_dimensions['G'].width = 20
ws.column_dimensions['H'].width = 20
ws.column_dimensions['I'].width = 20
ws.column_dimensions['J'].width = 20

# 保存
wb.save("test.xlsx")

数量で段階価格を判定する【Python>pandas】

数量によって単価が変化する価格表(いわゆる「段階価格」や「スライディング価格」)をExcelで管理していて、Pythonで図番と数量を入力すると該当する単価を抽出したい

◆Excel
・価格表.xlsx
図面番号/数量

・注文書.xlsx
図面番号/下限数量/上限数量/単価

◆コード


import pandas as pd

# 注文書と価格表の読み込み
df = pd.read_excel("注文書.xlsx")
df_kakaku = pd.read_excel("価格表.xlsx")

# 単価を検索する関数
def 単価検索(row):
    zumen = row['図面番号']
    suuryo = row['数量']
    
    # 該当する図面番号の価格帯を抽出
    kakaku_rows = df_kakaku[df_kakaku['図面番号'] == zumen]
    
    # 数量に該当する単価を抽出
    match = kakaku_rows[(kakaku_rows['下限数量'] <= suuryo) & (kakaku_rows['上限数量'] >= suuryo)]
    
    if match.empty:
        return None  # 該当なし
    return match.iloc[0]['単価']

# 注文書に単価列を追加
df['単価'] = df.apply(単価検索, axis=1)

# 出力
df.to_excel("output.xlsx", index=False)

shutil基礎【python】

ファイルをコピーする

import shutil
import os

# コピーするファイルのパス
source_path = r"C:\Users\***\test.xlsx"
# 目的のフォルダ
out_folder = r"C:\Users\***\out\"
# フォルダが存在しない場合、作成する
if not os.path.exists(out_folder):
    os.makedirs(out_folder)
# ファイルをコピー
out_path = os.path.join(out_folder, os.path.basename(source_path))
shutil.copy(source_path, out_path)

ファイルを移動する

# ファイルを移動
out_path = os.path.join(out_folder, os.path.basename(source_path))
shutil.move(source_path, out_path)

ファイルをコピーする(日付付きのファイル名に変更)

import shutil
import os
import datetime

# コピーするファイルのパス
source_path = r"C:\Users\***\test.xlsx"
# 目的のフォルダ
out_folder = r"C:\Users\***\out\"
# 今日の日付を取得してフォーマット(YYYYMMDD)
today_str = datetime.datetime.today().strftime("%Y%m%d")
# 新しいファイル名
new_filename = f"{today_str}_売上.xlsx"
# フォルダが存在しない場合、作成する
os.makedirs(out_folder, exist_ok=True)
# 新しいファイルのパスを作成
out_path = os.path.join(out_folder, new_filename)
# ファイルをコピー(新しい名前で)
shutil.copy(source_path, out_path)

フォルダ内の全てのファイルを移動する
(ファイル名がわからない場合orファイル名が固定ではない場合)

import glob
import os
import shutil

# 移動元フォルダ(Excel ファイルがある場所)
in_folder = r"C:\Users\***\in"

# 移動先フォルダ(ファイルを移動したい場所)
out_folder = r"C:\Users\***\out"

# 移動先フォルダが存在しない場合は作成
os.makedirs(out_folder, exist_ok=True)

# 指定フォルダ内のすべての Excel ファイルを取得
excel_files = glob.glob(os.path.join(in_folder, "*.xlsx"))

# ファイルを移動(既存のファイルがあれば上書き)
for file in excel_files:
    dst_file = os.path.join(out_folder, os.path.basename(file))  # 移動先のファイルパス
    shutil.copy2(file, dst_file)  # ファイルをコピー(上書き)
    os.remove(file)  # 元のファイルを削除

pandas基礎【Python】

よく使うコードのメモ

読み込み

df = pd.read_excel("test.xlsx")
df = pd.read_excel(r"C:\Users\***\python\test.xlsx")
df = pd.read_csv("test.csv", encoding='shift_jis')
df = pd.read_csv("test.csv", encoding='cp932')
df = pd.read_csv("test.csv", encoding='utf-8')

列を指定して、読み込み

pd.read_excel("test.xlsx", usecols=[0, 3])
pd.read_excel("test.xlsx", usecols=['姓', '名'])

結合列の作成

df['姓'] = df['姓'].fillna('') # 「姓」列のNaNを空文字列で埋める
df['名'] = df['名'].fillna('') # 「名」列のNaNを空文字列で埋める
df['姓名'] = df['姓'] + df['名']

書き出し
絶対参照の場合は「r””」
絶対参照+変数の場合は「fr””」
to_csvは「encoding=’shift_jis’」(Excelで文字化けしない)

df.to_excel("output.xlsx", index=False)
df.to_excel(r"C:\Users\***\python\output.xlsx", index=False)
today_str = datetime.now().strftime("%Y%m%d")
df.to_excel(fr"C:\Users\***\python\{today_str}_output.xlsx", index=False)
df.to_csv("output.csv", index=False, encoding='shift_jis')
df.to_csv("output.csv", index=False, encoding='utf-8')

リネーム

df.rename(columns={'商品コード': 'ID'}, inplace=True)
df.rename(columns={'商品コード': 'ID', '商品名': '品名'}, inplace=True)

置換

df['型番'] = df['型番'].str.replace(" ", "", regex=False)

全角→半角変換

import jaconv
df['型番'] = df['型番'].apply(lambda x: jaconv.z2h(str(x), kana=False, digit=True, ascii=True))

日付フィルター(今日のみ)

df = pd.read_excel("sales_data.xlsx")
df["日付"] = pd.to_datetime(df["日付"]) # datetime型に変換
df["日付"] = df["日付"].dt.normalize() # 時刻情報を削除
# 日付設定
today = pd.Timestamp.today().normalize()  # 今日(時刻をクリア)
# 日付フィルター
df = df[df["日付"] == today]
df.to_excel("output.xlsx", index=False)

日付フィルター(今の会計年度以降)

df = pd.read_excel("sales_data.xlsx")
df["日付"] = pd.to_datetime(df["日付"]) # datetime型に変換
df["日付"] = df["日付"].dt.normalize() # 時刻情報を削除
# 日付設定
today = pd.Timestamp.today().normalize()  # 今日(時刻をクリア)
current_year = today.year if today.month >= 4 else today.year - 1  # 4月以降ならその年、3月までなら前年
fiscal_start_date = pd.Timestamp(f"{current_year}-04-01")  # 会計年度
# 日付フィルター
start_day = fiscal_start_date  # 開始日
df = df[(df["日付"] >= start_day)]
df.to_excel("output.xlsx", index=False)

日付フィルター(前月の1ヶ月間)

df = pd.read_excel("sales_data.xlsx")
df["日付"] = pd.to_datetime(df["日付"]) # datetime型に変換
df["日付"] = df["日付"].dt.normalize() # 時刻情報を削除
# 日付設定
today = pd.Timestamp.today().normalize()  # 今日(時刻をクリア)
this_month_start = today.replace(day=1)  # 今月の初日
last_month_start = this_month_start - pd.DateOffset(months=1)  # 先月の初日
# 日付フィルター
start_day = last_month_start  # 開始日
end_day = this_month_start  # 終了日
df = df[(df["日付"] >= start_day) & (df["日付"] < end_day)]
df.to_excel("test.xlsx", index=False)

※日付設定集

today = pd.Timestamp.today().normalize()  # 今日(時刻をクリア)
yesterday = today - pd.Timedelta(days=1)  # 昨日の日付を計算
one_month_ago = today - pd.DateOffset(months=1)  # 1か月前
one_year_ago = today - pd.DateOffset(years=1)  # 1年前
specific_date = pd.Timestamp("2025-05-01")  # 特定の日
# 会計年度
current_year = today.year if today.month >= 4 else today.year - 1  # 4月以降ならその年、3月までなら前年
fiscal_start_date = pd.Timestamp(f"{current_year}-04-01")  # 会計年度
# 前月~今月~次月
this_month_start = today.replace(day=1)  # 今月の初日
next_month_start = this_month_start + pd.DateOffset(months=1)  # 次月の初日(=今月の最終日の翌日)
last_month_start = this_month_start - pd.DateOffset(months=1)  # 先月の初日

条件フィルター

df = df[~df['姓'].str.contains('田中', na=False)]  # 含む
df = df[df['姓'] != '田中']  # 完全一致
df = df[df['年齢'] >= 20]  # 条件式

並び替え(デフォルト昇順)

df = df.sort_values(by='年齢')  # 昇順(小さい値から大きい値へ)
df = df.sort_values(by='年齢', ascending=False)  # 降順(大きい値から小さい値へ)

重複の削除(デフォルトkeep='first')

df = df.drop_duplicates(subset=['ID'])
df = df.drop_duplicates(subset=['ID'], keep='last')

マージ

df = pd.merge(df, df_2, on='ID', how='left')

必要な列のみ出力

df = df[['姓名', 'ID']]

pandasでExcelデータの分割保存【Python】

Excelデータの分割保存
やりたいこと:年間や月間の売上データを、月毎や日毎のデータに分割して保存する。

月ごとに別ファイルとして保存

import pandas as pd
import os

# Excel ファイルの読み込み
df = pd.read_excel("sales_data.xlsx")  # 読み込むファイル名を指定
# 日付を datetime 型に変換
df["日付"] = pd.to_datetime(df["日付"])
# 保存用フォルダ作成
os.makedirs("monthly_reports", exist_ok=True)
# 月ごとに別ファイルとして保存
for month, data in df.groupby(df["日付"].dt.month):
    filename = f"monthly_reports/{month}_sales.xlsx"
    data.to_excel(filename, index=False)

会計年度ごとに別ファイルとして保存

# 日付を datetime 型に変換
df["日付"] = pd.to_datetime(df["日付"])
# 会計年度を算出(4月から翌年3月を1会計年度とする)
df["年度"] = df["日付"].apply(lambda x: x.year if x.month >= 4 else x.year - 1)
# 保存用フォルダ作成
os.makedirs("fiscal_reports", exist_ok=True)
# 会計年度ごとに別ファイルとして保存
for year, data in df.groupby(df["年度"]):
    filename = f"fiscal_reports/{year}_fiscal_sales.xlsx"
    data.to_excel(filename, index=False)

日ごとに別ファイルとして保存

import pandas as pd
import os

# Excel ファイルの読み込み
file_path = "sales_data.xlsx"
df = pd.read_excel(file_path)
# 日付を datetime 型に変換
df["日付"] = pd.to_datetime(df["日付"])
# 当月の1日と月末を取得
start_date = pd.to_datetime("today").replace(day=1)
end_date = start_date + pd.offsets.MonthEnd(0)
# 当月のデータのみを抽出
df_filtered = df[(df["日付"] >= start_date) & (df["日付"] <= end_date)]
# 保存用フォルダ作成
os.makedirs("daily_reports", exist_ok=True)
# 日ごとに別ファイルとして保存(ファイル名を YYYYMMDD 形式に変更)
for date, data in df_filtered.groupby(df_filtered["日付"].dt.date):
    filename = f"daily_reports/{date.strftime('%Y%m%d')}_sales.xlsx"
    data.to_excel(filename, index=False)

# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
import jaconv
import glob
import os
import shutil

folder_path = r"C:\***"  # フォルダのパス
excel_files = glob.glob(os.path.join(folder_path, "*.xlsx"))

# ファイルが存在するか確認
if excel_files:
    first_excel_file = excel_files[0]
    df = pd.read_excel(first_excel_file, engine="openpyxl")
    df.to_excel("temp.xlsx", index=False, header=False)#非標準ファイル対策
    df = pd.read_excel("temp.xlsx", engine="openpyxl")#非標準ファイル対策
    df = df[df.iloc[:, 7].notnull()]  # 7列目(H列)がNaNでない行を抽出
    df.columns = df.iloc[0]# 1行目を列名として設定
    df = df[1:].reset_index(drop=True)  # 1行目を削除し、インデックスを再設定
    
    df.to_excel("end.xlsx", index=False)
    
else:
    print("Excelファイルが見つかりませんでした。")