月次レポート機能の改善として、開始日・終了日によるフィルタリング機能を追加し、店舗区分および経費区分の選択肢を実装。経費区分と店舗マスタの管理画面を新規作成し、関連するマイグレーションを追加。CSV取込画面における経費区分の表示を改善。作業ログをdiary.mdに追記。
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
<nav>
|
||||
<a href="{% url 'csv_upload' %}">CSV取込</a>
|
||||
<a href="{% url 'expense_list' %}">明細編集</a>
|
||||
<a href="{% url 'store_master' %}">店舗マスタ</a>
|
||||
<a href="{% url 'expense_category_master' %}">経費区分マスタ</a>
|
||||
<a href="{% url 'monthly_report' %}">月次レポート</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
74
templates/expenses/expense_category_master.html
Normal file
74
templates/expenses/expense_category_master.html
Normal file
@@ -0,0 +1,74 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}経費区分マスタ管理{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<h2>経費区分マスタ管理</h2>
|
||||
{% if error_message %}
|
||||
<p>{{ error_message }}</p>
|
||||
{% endif %}
|
||||
<h3>経費区分を追加</h3>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<label>
|
||||
経費区分名
|
||||
<input type="text" name="name" required>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="is_active" value="1" checked>
|
||||
有効
|
||||
</label>
|
||||
<button type="submit">追加</button>
|
||||
</form>
|
||||
<h3>一覧</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>経費区分名</th>
|
||||
<th>有効</th>
|
||||
<th>更新</th>
|
||||
<th>削除</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for category in categories %}
|
||||
<tr>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="category_id" value="{{ category.id }}">
|
||||
<td>
|
||||
<input type="text" name="name" value="{{ category.name }}" required>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="is_active"
|
||||
value="1"
|
||||
{% if category.is_active %}checked{% endif %}
|
||||
>
|
||||
</td>
|
||||
<td>
|
||||
<button type="submit">保存</button>
|
||||
</td>
|
||||
</form>
|
||||
<td>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="category_id" value="{{ category.id }}">
|
||||
<input type="hidden" name="action" value="deactivate">
|
||||
<button type="submit" {% if not category.is_active %}disabled{% endif %}>
|
||||
無効化
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4">経費区分がありません。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -129,6 +129,12 @@
|
||||
}
|
||||
|
||||
function coerceValue(field, value) {
|
||||
if (value === '') {
|
||||
return value;
|
||||
}
|
||||
if (field === 'store_id' || field === 'expense_category_id') {
|
||||
return Number(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,14 +8,87 @@
|
||||
<h2>月次レポート</h2>
|
||||
<form method="get">
|
||||
<label>
|
||||
年月
|
||||
<input type="month" name="target_month" value="{{ target_month }}">
|
||||
開始日
|
||||
<input type="date" name="start_date" value="{{ start_date }}">
|
||||
</label>
|
||||
<label>
|
||||
終了日
|
||||
<input type="date" name="end_date" value="{{ end_date }}">
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="all_time" value="1" {% if all_time %}checked{% endif %}>
|
||||
全期間
|
||||
</label>
|
||||
<label>
|
||||
店舗区分
|
||||
<select name="store_id">
|
||||
<option value="" {% if not selected_store %}selected{% endif %}>全て</option>
|
||||
<option value="unassigned" {% if selected_store == "unassigned" %}selected{% endif %}>
|
||||
未設定
|
||||
</option>
|
||||
{% for store in stores %}
|
||||
<option value="{{ store.id }}" {% if selected_store == store.id|stringformat:"s" %}selected{% endif %}>
|
||||
{{ store.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
経費区分
|
||||
<select name="expense_category_id">
|
||||
<option value="" {% if not selected_category %}selected{% endif %}>全て</option>
|
||||
<option value="unassigned" {% if selected_category == "unassigned" %}selected{% endif %}>
|
||||
未設定
|
||||
</option>
|
||||
{% for category in categories %}
|
||||
<option value="{{ category.id }}" {% if selected_category == category.id|stringformat:"s" %}selected{% endif %}>
|
||||
{{ category.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
利用先
|
||||
<input type="search" name="description" value="{{ description_query }}">
|
||||
</label>
|
||||
<input type="hidden" name="show" value="1">
|
||||
<button type="submit">表示</button>
|
||||
{% if show_report %}
|
||||
<a
|
||||
href="{% url 'monthly_report_pdf' %}?start_date={{ start_date }}&end_date={{ end_date }}&store_id={{ selected_store }}&expense_category_id={{ selected_category }}&description={{ description_query|urlencode }}&all_time={% if all_time %}1{% endif %}"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
PDF出力
|
||||
</a>
|
||||
{% endif %}
|
||||
</form>
|
||||
<script>
|
||||
const startInput = document.querySelector('input[name="start_date"]');
|
||||
const endInput = document.querySelector('input[name="end_date"]');
|
||||
const allTimeInput = document.querySelector('input[name="all_time"]');
|
||||
if (startInput && endInput && allTimeInput) {
|
||||
const syncAllTime = () => {
|
||||
if (startInput.value || endInput.value) {
|
||||
allTimeInput.checked = false;
|
||||
}
|
||||
};
|
||||
startInput.addEventListener('change', syncAllTime);
|
||||
endInput.addEventListener('change', syncAllTime);
|
||||
allTimeInput.addEventListener('change', () => {
|
||||
if (allTimeInput.checked) {
|
||||
startInput.value = '';
|
||||
endInput.value = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% if error_message %}
|
||||
<p style="color: #b00020;">{{ error_message }}</p>
|
||||
{% endif %}
|
||||
{% if not show_report %}
|
||||
<p>条件を指定して表示ボタンを押してください。</p>
|
||||
{% else %}
|
||||
<div>
|
||||
<h3>合計</h3>
|
||||
<p class="amount">{{ report.total_amount|intcomma }} 円</p>
|
||||
@@ -50,6 +123,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日付</th>
|
||||
<th>経費区分</th>
|
||||
<th>利用先</th>
|
||||
<th class="amount">金額</th>
|
||||
<th>備考</th>
|
||||
@@ -59,13 +133,14 @@
|
||||
{% for detail in row.details %}
|
||||
<tr>
|
||||
<td>{{ detail.use_date }}</td>
|
||||
<td>{{ detail.expense_category_name|default:"未設定" }}</td>
|
||||
<td>{{ detail.description }}</td>
|
||||
<td class="amount">{{ detail.amount|intcomma }}</td>
|
||||
<td>{{ detail.note }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4">対象データがありません。</td>
|
||||
<td colspan="5">対象データがありません。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -102,6 +177,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日付</th>
|
||||
<th>経費区分</th>
|
||||
<th>利用先</th>
|
||||
<th class="amount">金額</th>
|
||||
<th>備考</th>
|
||||
@@ -111,13 +187,14 @@
|
||||
{% for detail in row.details %}
|
||||
<tr>
|
||||
<td>{{ detail.use_date }}</td>
|
||||
<td>{{ detail.expense_category_name|default:"未設定" }}</td>
|
||||
<td>{{ detail.description }}</td>
|
||||
<td class="amount">{{ detail.amount|intcomma }}</td>
|
||||
<td>{{ detail.note }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4">対象データがありません。</td>
|
||||
<td colspan="5">対象データがありません。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -154,6 +231,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日付</th>
|
||||
<th>経費区分</th>
|
||||
<th>利用先</th>
|
||||
<th class="amount">金額</th>
|
||||
<th>備考</th>
|
||||
@@ -163,13 +241,14 @@
|
||||
{% for detail in row.details %}
|
||||
<tr>
|
||||
<td>{{ detail.use_date }}</td>
|
||||
<td>{{ detail.expense_category_name|default:"未設定" }}</td>
|
||||
<td>{{ detail.description }}</td>
|
||||
<td class="amount">{{ detail.amount|intcomma }}</td>
|
||||
<td>{{ detail.note }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4">対象データがありません。</td>
|
||||
<td colspan="5">対象データがありません。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -185,5 +264,6 @@
|
||||
<li>対象総件数: {{ report.unclassified_counts.total }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>月次レポート</h1>
|
||||
<p>対象年月: {{ target_month }}</p>
|
||||
<p>対象期間: {{ target_period }}</p>
|
||||
<h2>合計</h2>
|
||||
<p class="amount">{{ report.total_amount|intcomma }} 円</p>
|
||||
<h2>店舗別合計</h2>
|
||||
|
||||
74
templates/expenses/store_master.html
Normal file
74
templates/expenses/store_master.html
Normal file
@@ -0,0 +1,74 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}店舗マスタ管理{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<h2>店舗マスタ管理</h2>
|
||||
{% if error_message %}
|
||||
<p>{{ error_message }}</p>
|
||||
{% endif %}
|
||||
<h3>店舗を追加</h3>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<label>
|
||||
店舗名
|
||||
<input type="text" name="name" required>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="is_active" value="1" checked>
|
||||
有効
|
||||
</label>
|
||||
<button type="submit">追加</button>
|
||||
</form>
|
||||
<h3>一覧</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>店舗名</th>
|
||||
<th>有効</th>
|
||||
<th>更新</th>
|
||||
<th>削除</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for store in stores %}
|
||||
<tr>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="store_id" value="{{ store.id }}">
|
||||
<td>
|
||||
<input type="text" name="name" value="{{ store.name }}" required>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="is_active"
|
||||
value="1"
|
||||
{% if store.is_active %}checked{% endif %}
|
||||
>
|
||||
</td>
|
||||
<td>
|
||||
<button type="submit">保存</button>
|
||||
</td>
|
||||
</form>
|
||||
<td>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="store_id" value="{{ store.id }}">
|
||||
<input type="hidden" name="action" value="deactivate">
|
||||
<button type="submit" {% if not store.is_active %}disabled{% endif %}>
|
||||
無効化
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4">店舗がありません。</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user