ken_nogi/pleasanter/develop/#リフォームラボ/■イオン多摩平シフト管理/sites/scripts/1.シフト希望表示.js
Kenichiro NOGI 7176dc33ec pleasanter
2025-07-10 10:15:35 +09:00

303 lines
11 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
@config : next999.json
@filename : ${psFileBasename}
@title : 1.シフト希望表示
@name :
@siteIds : 310511
@siteTitles : イオン多摩平シフト管理
@disabled: false
*/
let apiKey = '6504c8a807677a3a576e10327f3c19876c55736ee45d4a845796b9e7f5e087bfd4bd0d8184863da8cf1733ca635111432ab334aea59102b06a96ee6d2c05190d';
let subWin;
//シフト希望データの保存先
let subTableId = '310514';
let now = new Date();
let monthStr = now.getFullYear() + '年' +
(now.getMonth() + 1).toString().padStart(2, '0') + '月';
let shiftData;
let totalCount = 0;
// 名前とクラスのマッピング
const nameColorMap =
{
/*"豊蔵 恵美": { "backgroundColor": "#9370DB", "fontColor": "#000000" },
"長谷川 望": { "backgroundColor": "#008000", "fontColor": "#FFFFFF" },
"河村 あゆみ": { "backgroundColor": "#0000FF", "fontColor": "#FFFFFF" },
"渡部 直輝": { "backgroundColor": "#FFFF00", "fontColor": "#000000" },
"小坂 志織": { "backgroundColor": "#FFA500", "fontColor": "#000000" },
"佐藤 春樹": { "backgroundColor": "#800080", "fontColor": "#FFFFFF" },
"河関 宏昌": { "backgroundColor": "#FFC0CB", "fontColor": "#000000" },
"中嶋 透": { "backgroundColor": "#A52A2A", "fontColor": "#FFFFFF" },
"西川 眞": { "backgroundColor": "#F08080", "fontColor": "#000000" },
"岡本 祥子": { "backgroundColor": "#90EE90", "fontColor": "#000000" },
"青柳 麻衣": { "backgroundColor": "#ADD8E6", "fontColor": "#000000" },
"田渕 希美": { "backgroundColor": "#FFFFE0", "fontColor": "#000000" },
"松村 花純": { "backgroundColor": "#FFDAB9", "fontColor": "#000000" },
"菱田 朱夏": { "backgroundColor": "#E6E6FA", "fontColor": "#000000" },
"奥山 喜美花": { "backgroundColor": "#FFB6C1", "fontColor": "#000000" },
"山口 賢人": { "backgroundColor": "#DEB887", "fontColor": "#000000" },
"小島 芙優": { "backgroundColor": "#E0FFFF", "fontColor": "#000000" },
"滝澤 みづき": { "backgroundColor": "#DA70D6", "fontColor": "#000000" },
"八代 美波": { "backgroundColor": "#20B2AA", "fontColor": "#000000" },
"伊藤 亜子": { "backgroundColor": "#32CD32", "fontColor": "#000000" },
"鈴木 梨紗都": { "backgroundColor": "#D8BFD8", "fontColor": "#000000" },*/
"店長会議": { "backgroundColor": "#000000", "fontColor": "#FFFFFF" },
"イオンセミナー": { "backgroundColor": "#DC143C", "fontColor": "#FFFFFF" },
"説明会": { "backgroundColor": "#4B0082", "fontColor": "#FFFFFF" },
"ティッシュ配布": { "backgroundColor": "#FFD700", "fontColor": "#000000" },
"消防訓練": { "backgroundColor": "#800000", "fontColor": "#FFFFFF" },
"欠員": { "backgroundColor": "#FF0000", "fontColor": "#FFFFFF" },
"法定点検": { "backgroundColor": "#800000", "fontColor": "#FFFFFF" },
"ラック申請": { "backgroundColor": "#00FFFF", "fontColor": "#000000" },
"チラシ申請": { "backgroundColor": "#00FFFF", "fontColor": "#000000" },
"アプリ申請": { "backgroundColor": "#00FFFF", "fontColor": "#000000" },
}
$p.events.on_calendar_load = function () {
//処理内容
$p.ex.init('#Calendar');
//ペンマークの削除
$('div.title>.ui-icon-pencil').remove();
//色分け
$('div.item').each(function () {
const $item = $(this);
const itemId = $item.attr('data-id');
const span = '<span class="ui-icon ui-icon-check custom-check" data-id="' + itemId + '" style="cursor:pointer;"></span>';
// $(this)の子タグの下にspanを追加
$(this).children().last().prepend(span);
const titleText = $(this).text().trim();
const name = titleText.split('-')[0].trim();
const startTime = titleText.split('-')[1]?.trim() || '';
const endTime = titleText.split('-')[2]?.trim() || '';
const restTime = endTime && startTime ? Math.max(0, parseInt(endTime, 10) - parseInt(startTime, 10) - 4) : 0;
if (restTime > 0) {
$(this).css('background-color', 'yellow');
$(this).css('color', 'black');
$(this).css('border', '2px solid black'); // 休憩時間がある場合は赤枠
} else {
$(this).css('border', '1px dashed black'); // 休憩時間がない場合は透明な枠
}
$(this).css('background-color', nameColorMap[name]?.backgroundColor);
$(this).css('color', nameColorMap[name]?.fontColor);
});
// クリックイベントを追加
$(document).off('click', '.custom-check').on('click', '.custom-check', function (e) {
e.stopPropagation();
const itemId = $(this).data('id');
$p.ex.changeTimeDataWindow(itemId, e.pageX, e.pageY);
});
$('span.data.link').each(function () {
const titleText = $(this).text().trim();
const name = titleText.split(/\d+/)[0].trim();
$(this).css('background-color', nameColorMap[name]?.backgroundColor);
$(this).css('color', nameColorMap[name]?.fontColor);
});
}
$p.events.on_editor_load = function () {
//処理内容
$p.ex.init('#EditorTabsContainer');
}
$p.events.on_grid_load = function () {
//処理内容
$p.ex.init('.grid-wrap');
}
$p.ex.init = function (target) {
$(target).css({
'width': '60%',
'float': 'left'
});
//ウインドウがすでにある場合は削除
if ($('#shiftListWindow').length) $('#shiftListWindow').remove();
subWin = document.createElement('div');
subWin.id = 'shiftListWindow';
subWin.innerText = '';
subWin.style.width = '40%';
subWin.style.float = 'left';
subWin.style.textAlign = 'center';
$(target).after(subWin);
let savedMonth = localStorage.getItem('selectedMonth');
let initialMonth = savedMonth || monthStr;
//シフトデータ挿入
$p.ex.getShiftKibouData(initialMonth);
}
$p.events.before_validate = function (args) {
}
//シフト希望日データ取得
$p.ex.getShiftKibouData = async function (monthStr) {
//プリザンターへゲット処理
const pleasanterUrl = 'https://' + location.hostname + '/pleasanter/api/items/' + subTableId + '/get'
const jsonBody = {
'ApiVersion': 1.1,
'ApiKey': apiKey,
'View': {
'ColumnSorterHash': {
'ClassB': 'asc'
},
'ColumnFilterHash': {
'ClassA': '["' + monthStr + '"]'
},
}
};
const pleasanterRes = await fetch(pleasanterUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(jsonBody)
});
const resData = await pleasanterRes.json();
//console.log(resData);
//リスト消して
if ($('#listTable').length) $('#listTable').remove();
if ($('#monthSelect').length) $('#monthSelect').remove();
// 年月セレクトボックス作成
let now = new Date();
// ローカルストレージから選択値を取得
let savedMonth = localStorage.getItem('selectedMonth');
let initialMonth = savedMonth || monthStr;
let selectHtml = `<select id="monthSelect">`;
for (let i = 0; i < 4; i++) {
let d = new Date(now.getFullYear(), now.getMonth() + i, 1);
let y = d.getFullYear();
let m = (d.getMonth() + 1).toString().padStart(2, '0');
let ym = `${y}${m}`;
let selected = (ym === initialMonth) ? 'selected' : '';
selectHtml += `<option value="${ym}" ${selected}>${ym}</option>`;
}
selectHtml += `</select>`;
// テーブルテンプレート
let templateHtml =
`<table id="listTable" class="radius-table">
<tr>
<th>名前</th>
<th>希望シフト内容</th>
</tr>
{{#listData}}
<tr class="{{type}}">
<td class="userName">{{userName}}</td>
<td>{{shiftData}}</td>
</tr>
{{/listData}}
</table>`;
let listData = [];
let userName = '   ';
let userName0;
//シフト希望データの作成
shiftData = '名前,種別,勤務可能日,勤務可能時間帯,その他条件\n';
$.each(resData.Response.Data, function (index, value) {
if (userName0 != value.ClassHash.ClassX) {
userName = value.ClassHash.ClassX;
} else {
userName = '   ';
}
let data = {
'userName': userName,
'shiftData': value.ClassHash.ClassZ
}
listData.push(data);
userName0 = value.ClassHash.ClassX;
//AI用のシフトデーt作成
let dateList = JSON.parse(value.ClassHash.ClassW).join('');
//let weekList = JSON.parse(value.ClassHash.ClassC).join('');
let timeList = JSON.parse(value.ClassHash.ClassD).join('');
//shiftData += `${value.ClassHash.ClassX},${value.ClassHash.ClassP},${value.ClassHash.ClassZ},${value.ClassHash.ClassE},${value.ClassHash.ClassF},${value.ClassHash.ClassG},${value.ClassHash.ClassH}\n`;
shiftData += `${value.ClassHash.ClassX},${value.ClassHash.ClassP},${dateList},${timeList},${value.ClassHash.ClassF}\n`;
});
//最後に欠員の情報を配置
shiftData += '欠員,社員,いつでも,いつでも,いつでも,他の社員が勤務している時間帯は不可,他のメンバーの勤務を優先し、誰も割当できない時間帯に勤務する\n';
//console.log(shiftData);
let template = Hogan.compile(templateHtml);
let outputHtml = template.render({
"listData": listData
});
// selectボックスとテーブルを挿入
$('#shiftListWindow').append(selectHtml + outputHtml);
// ▼▼ ここからボタン追加 ▼▼
// 既存のボタンがあれば削除
if ($('#generateShiftBtn').length) $('#generateShiftBtn').remove();
if ($('#deleteShiftDataBtn').length) $('#deleteShiftDataBtn').remove();
// ボタンを作成してテーブルの下に追加
const $btn1 = $('<button id="generateShiftBtn" style="margin:10px;padding:8px 24px;font-size:1.1em;border-radius:8px;background:#0078d7;color:#fff;border:none;cursor:pointer;">AIでシフト自動生成</button>');
// ボタンを作成してテーブルの下に追加
const $btn2 = $('<button id="deleteShiftDataBtn" style="margin:10px;padding:8px 24px;font-size:1.1em;border-radius:8px;background:#0078d7;color:#fff;border:none;cursor:pointer;">シフトをすべて削除</button>');
//対象年月のシフトデータの件数を取得
getPleasanterCountByMonth().then(count => {
console.log('件数:' + count);
totalCount = count;
if (count > 0) {
$('#shiftListWindow').append($btn2);
$btn2.on('click', function () {
deletePleasanterDataByDateRange();
});
//$('#deleteShiftDataBtn').show();
} else {
$('#shiftListWindow').append($btn1);
//$('#deleteShiftDataBtn').hide();
}
});
// ボタンクリック時にcreatePrompotText(shiftData)を実行
$btn1.on('click', function () {
createPrompotText(shiftData);
});
// ▲▲ ここまでボタン追加 ▲▲
// selectボックスのイベント
$('#monthSelect').on('change', function () {
let selectedMonth = $(this).val();
// 選択値をローカルストレージに保存
localStorage.setItem('selectedMonth', selectedMonth);
$p.ex.getShiftKibouData(selectedMonth);
});
}