app/template/user_data/delivery_confirmation.twig line 1

Open in your IDE?
  1. {% extends '@user_data/layout/default_frame.twig' %}
  2. {% block title %}
  3. 納期・発送日確認 | オリジナル缶バッジ/カンバッチ製作【個人小ロットから業務用OEMまで激安印刷】ZEAMI Goods
  4. {% endblock %}
  5. {% block js %}
  6. {# https://www.npmjs.com/package/japanese-holidays #}
  7. <script src="{{ asset('assets/js/holiday_calender.js') }}" type="text/javascript"></script>
  8. <script>
  9. document.addEventListener('DOMContentLoaded', async (event) => {
  10. const today = new Date();
  11. const year = today.getFullYear();
  12. const month = today.getMonth();
  13. const date = today.getDate();
  14. const firstDayOfMonth = new Date(year, month, 1).getDay();
  15. const lastDateOfMonth = new Date(year, month + 1, 0).getDate();
  16. const lastDayOfMonth = new Date(year, month, lastDateOfMonth).getDay();
  17. const lastDateOfPreviousMonth = new Date(year, month, 0).getDate();
  18. const calendarMonth = document.querySelector('.calender_month');
  19. const calendarTable = document.querySelector('.calender_table tbody');
  20. const workingtimes = {{ workingtimes|json_encode|raw }};
  21. const months = [
  22. "1月",
  23. "2月",
  24. "3月",
  25. "4月",
  26. "5月",
  27. "6月",
  28. "7月",
  29. "8月",
  30. "9月",
  31. "10月",
  32. "11月",
  33. "12月"
  34. ];
  35. calendarMonth.textContent = `${year}年${
  36. months[month]
  37. }`;
  38. let calendarHTML = '';
  39. let dateCounter = 1;
  40. let nextMonthDateCounter = 1;
  41. for (let row = 0; row < 6; row++) {
  42. calendarHTML += '<tr class="date">';
  43. for (let day = 0; day < 7; day++) {
  44. if (row === 0 && day < firstDayOfMonth) {
  45. calendarHTML += `<td class="other_month">${
  46. lastDateOfPreviousMonth - firstDayOfMonth + day + 1
  47. }</td>`;
  48. } else if (dateCounter > lastDateOfMonth) {
  49. calendarHTML += `<td class="other_month">${nextMonthDateCounter}</td>`;
  50. nextMonthDateCounter++;
  51. } else {
  52. let className = '';
  53. if (day === 0 || day === 6) {
  54. className = 'rest';
  55. }
  56. if (dateCounter === date && month === today.getMonth() && year === today.getFullYear()) {
  57. className = 'active';
  58. }
  59. const time = new Date(`${year}-${month + 1}-${dateCounter}`);
  60. const holiday = JapaneseHolidays.isHoliday(time);
  61. if (holiday) {
  62. className = 'holiday';
  63. }
  64. let current_date = `${year}-${month + 1}-${dateCounter}`;
  65. for(let i = 0; i < workingtimes.length; i++) {
  66. if((workingtimes[i]['date'].replace('-0', '-') == current_date) && workingtimes[i]['status']) {
  67. className = 'holiday';
  68. } else if((workingtimes[i]['date'].replace('-0', '-') == current_date )&& !workingtimes[i]['status']) {
  69. className = 'working'
  70. }
  71. }
  72. calendarHTML += `<td class="${className}">${dateCounter}</td>`;
  73. dateCounter++;
  74. }
  75. }
  76. calendarHTML += '</tr>';
  77. }
  78. await calendarTable.insertAdjacentHTML('beforeend', calendarHTML);
  79. });
  80. document.addEventListener('DOMContentLoaded', async (event) => {
  81. const today = new Date();
  82. const year = today.getFullYear();
  83. const month = today.getMonth() + 1;
  84. const date = today.getDate();
  85. const firstDayOfMonth = new Date(year, month, 1).getDay();
  86. const lastDateOfMonth = new Date(year, month + 1, 0).getDate();
  87. const lastDayOfMonth = new Date(year, month, lastDateOfMonth).getDay();
  88. const lastDateOfPreviousMonth = new Date(year, month, 0).getDate();
  89. const calendarMonth = document.querySelector('.calender_next_month');
  90. const calendarTable = document.querySelector('.calender_next_table tbody');
  91. const workingtimes = {{ workingtimes|json_encode|raw }};
  92. const months = [
  93. "1月",
  94. "2月",
  95. "3月",
  96. "4月",
  97. "5月",
  98. "6月",
  99. "7月",
  100. "8月",
  101. "9月",
  102. "10月",
  103. "11月",
  104. "12月"
  105. ];
  106. calendarMonth.textContent = month == 12 ? `${year + 1}年${months[0]}` : `${year}年${months[month]}`;
  107. let calendarHTML = '';
  108. let dateCounter = 1;
  109. let nextMonthDateCounter = 1;
  110. for (let row = 0; row < 6; row++) {
  111. calendarHTML += '<tr class="date">';
  112. for (let day = 0; day < 7; day++) {
  113. if (row === 0 && day < firstDayOfMonth) {
  114. calendarHTML += `<td class="other_month">${lastDateOfPreviousMonth - firstDayOfMonth + day + 1}</td>`;
  115. } else if (dateCounter > lastDateOfMonth) {
  116. calendarHTML += `<td class="other_month">${nextMonthDateCounter}</td>`;
  117. nextMonthDateCounter++;
  118. } else {
  119. let className = '';
  120. if (day === 0 || day === 6) {
  121. className = 'rest';
  122. }
  123. if (dateCounter === date && month === today.getMonth() && year === today.getFullYear()) {
  124. className = 'active';
  125. }
  126. const time = month == 12 ? new Date(`${year + 1}-${1}-${dateCounter}`): new Date(`${year}-${month + 1}-${dateCounter}`);
  127. const holiday = JapaneseHolidays.isHoliday(time);
  128. if (holiday) {
  129. className = 'holiday';
  130. }
  131. let current_date = `${year}-${month + 1}-${dateCounter}`;
  132. for(let i = 0; i < workingtimes.length; i++) {
  133. if((workingtimes[i]['date'].replace('-0', '-') == current_date) && workingtimes[i]['status']) {
  134. className = 'holiday';
  135. } else if((workingtimes[i]['date'].replace('-0', '-') == current_date )&& !workingtimes[i]['status']) {
  136. className = 'working'
  137. }
  138. }
  139. calendarHTML += `<td class="${className}">${dateCounter}</td>`;
  140. dateCounter++;
  141. }
  142. }
  143. calendarHTML += '</tr>';
  144. }
  145. calendarTable.insertAdjacentHTML('beforeend', calendarHTML);
  146. const now = new Date();
  147. const checkHoliday = checkIsHoliday(now, workingtimes);
  148. if(checkHoliday) {
  149. $('.working-time').hide();
  150. $('.holiday-time').show();
  151. } else {
  152. $('.holiday-time').hide();
  153. $('.working-time').show();
  154. }
  155. if(checkHoliday) {
  156. let nextBusiness = null;
  157. do {
  158. now.setDate(now.getDate() + 1);
  159. nextBusiness = now;
  160. } while (checkIsHoliday(now, workingtimes));
  161. $('.holiday-time').text('翌営業日『' + formatDateJP(nextBusiness) + '』ご注文確定の場合、下記日程で発送いたします。')
  162. }
  163. });
  164. function checkIsHoliday(date, workingtimes) {
  165. date = formatDate(date);
  166. const now_time = new Date(date);
  167. const holiday = JapaneseHolidays.isHoliday(now_time);
  168. let check = false;
  169. if(holiday) {
  170. check = true;
  171. } else {
  172. check = false;
  173. }
  174. for(let i = 0; i < workingtimes.length; i++) {
  175. if((workingtimes[i]['date'] == date) && workingtimes[i]['status']) {
  176. check = true;
  177. } else if((workingtimes[i]['date'] == date )&& !workingtimes[i]['status']) {
  178. check = false;
  179. }
  180. }
  181. return check;
  182. }
  183. function formatTimeDelivery(totalDay) {
  184. const workingtimes = {{ workingtimes|json_encode|raw }};
  185. let working_time = [];
  186. let holiday_time = [];
  187. for(let i = 0; i < workingtimes.length; i++) {
  188. if(workingtimes[i].status) {
  189. holiday_time.push(workingtimes[i].date);
  190. } else {
  191. working_time.push(workingtimes[i].date);
  192. }
  193. }
  194. const now = new Date();
  195. now.setDate(now.getDate() + 1);
  196. let index = 0;
  197. for(let i = 0; i < totalDay; i++) {
  198. const holiday = JapaneseHolidays.isHoliday(now);
  199. if(holiday || now.getDay() == 6 || now.getDay() == 0) {
  200. if(!working_time.includes(formatDate(now))) {
  201. index++;
  202. }
  203. }
  204. if(holiday_time.includes(formatDate(now))) {
  205. index++;
  206. }
  207. now.setDate(now.getDate() + 1);
  208. }
  209. while((JapaneseHolidays.isHoliday(now) || now.getDay() == 6 || now.getDay() == 0 || holiday_time.includes(formatDate(now))) && !working_time.includes(formatDate(now))) {
  210. now.setDate(now.getDate() + 1);
  211. }
  212. now.setDate(now.getDate() + index);
  213. while((JapaneseHolidays.isHoliday(now) || now.getDay() == 6 || now.getDay() == 0 || holiday_time.includes(formatDate(now))) && !working_time.includes(formatDate(now))) {
  214. now.setDate(now.getDate() + 1);
  215. }
  216. return formatDateJP(now);
  217. }
  218. function formatDate(date) {
  219. const year = date.getFullYear();
  220. const month = String(date.getMonth() + 1).padStart(2, '0');
  221. const day = String(date.getDate()).padStart(2, '0');
  222. return `${year}-${month}-${day}`;
  223. }
  224. function formatDateJP(time) {
  225. const daysOfWeek = ['日', '月', '火', '水', '木', '金', '土'];
  226. const year = time.getFullYear();
  227. const month = time.getMonth() + 1;
  228. const day = time.getDate();
  229. const dayOfWeek = time.getDay();
  230. return `${year}年${month}月${day}日(${daysOfWeek[dayOfWeek]})`;
  231. }
  232. </script>
  233. <script>
  234. $(document).ready(function () {
  235. $('input[type=radio][name=category]').change(function () {
  236. let cate = this.value;
  237. const admin_router = "{{ eccube_config.eccube_admin_route }}";
  238. $.ajax({
  239. url: `/category-products/` + cate,
  240. dataType: 'json', // added data type
  241. success: function (res) {
  242. $('.product-block').show();
  243. let html = '';
  244. for (let i = 0; i < res.products.length; i++) {
  245. html += `
  246. <li class="type_check up moveup">
  247. <label style="display: flex !important"><input type="radio" onchange="handleProductChange(this)" name="product" value="${res.products[i].id}" class="form_check"/>
  248. <span></span>
  249. <div style="text-wrap: wrap;width: 60%;">${res.products[i].name}</div>
  250. </label>
  251. </li>
  252. `;
  253. }
  254. $('.product-list').html(html);
  255. }
  256. });
  257. });
  258. });
  259. function handleProductChange(radio) {
  260. var selectedProductId = radio.value;
  261. $.ajax({
  262. url: `/get_delivery/`+selectedProductId,
  263. dataType: 'json', // added data type
  264. success: function (res) {
  265. $('.add_line').remove();
  266. $('.delivery_confirm').show();
  267. let html = '';
  268. for (let i = 0; i < res.data.length; i++) {
  269. html += `
  270. <tr class="add_line">
  271. <td class="table_headline">
  272. <p>${res.data[i].quantity}</p>
  273. </td>
  274. `;
  275. for(let j = 0; j < res.data[i].options.length; j++) {
  276. if(res.data[i].options[j].deliverty_time == '0') {
  277. html += `
  278. <td>
  279. <p class="delivery_date" style="min-width: 50px">-</p>
  280. </td>
  281. `;
  282. } else {
  283. html += `
  284. <td>
  285. <p class="delivery_date">${res.data[i].options[j].deliverty_time}営業日後発送</p><br>${formatTimeDelivery(res.data[i].options[j].deliverty_time)}
  286. </td>
  287. `;
  288. }
  289. }
  290. html += `
  291. </tr>
  292. `;
  293. }
  294. $('#root-table').after(html);
  295. }
  296. });
  297. }
  298. async function checkStatusDate(date) {
  299. return new Promise((resolve, reject) => {
  300. $.ajax({
  301. url: "{{ url('workingtime_check_status') }}",
  302. method: 'POST',
  303. data: {
  304. date: date,
  305. },
  306. dataType: 'json',
  307. success: function(res) {
  308. resolve(res.result);
  309. },
  310. error: function(err) {
  311. reject(err);
  312. }
  313. });
  314. });
  315. }
  316. </script>
  317. {% endblock %}
  318. {% block content %}
  319. <!-- // ++ パンクズ ++ //////////////////////////////////////////////////////////// // -->
  320. <div id="bread_crumbBloc" class="fades">
  321. <ul id="breadCrumb" class="fades">
  322. <li class="up">
  323. <a href="/"><img src="{{ asset('assets/img/icon_home.png') }}" alt="ホーム"></a>
  324. </li>
  325. <li class="up">納期・発送日確認</li>
  326. </ul>
  327. <!-- ///// #breadCrumb +++++ ///// -->
  328. <!-- ///// +++++ #bread_crumbBloc +++++ ///// -->
  329. </div>
  330. <!-- ▼▼ MAIN CONTENTS __________________________________________________________________________________________________ ▼▼ -->
  331. <main
  332. id="mainContents" class="">
  333. <!-- // == MAIN ================================================================================ // -->
  334. <section
  335. id="Confirm" class="section_basic full">
  336. <!-- // ++ ページタイトル ++ /////////////////////////////////////////////////////////////// -->
  337. <div id="section_titleBloc" class="fades twolayout_body">
  338. <div id="title_twoLayout">
  339. <h3 class="section_title up">納期・発送日確認</h3>
  340. <p class="title_cap up">ご注文確定の日より、当店から出荷の日をご確認いただけます</p>
  341. <p class="section_note up">デザイン決定後、ご決済いただき次第ご注文確定となります。個人のお客様で銀行振込をご選択の場合、ご入金を確認次第ご注文確定となりますのでご注意ください。
  342. ヤマト運輸をご選択の場合、到着時間帯をご指定可能です。(午前中、14~16時、16~18時、18~20時、19~21時)<br>
  343. 日本国外発送可能 International delivery</p>
  344. </div>
  345. <!-- //// ++++ #title_twoLayout ++++ //// -->
  346. <figure id="titlePic" class="two_layout"><img src="{{ asset('assets/img/delivery/confirm_title_pic.jpg') }}"></figure>
  347. <!-- ///// #section_titleBloc +++++ ///// -->
  348. </div>
  349. <!-- // ++ 営業日カレンダー ++ /////////////////////////////////////////////////////////////// -->
  350. <div id="Calender" class="one_box fades">
  351. <div
  352. class="calender_inner">
  353. <!-- // △△ 見出し ++ △△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△ -->
  354. <dl id="calender_titleArea" class="fades">
  355. <dt>
  356. <h4 id="calenderHeadline" class="up">
  357. <span>営業日カレンダー</span>
  358. </h4>
  359. </dt>
  360. <dd>
  361. <span id="markClosed" class="up"><img src="{{ asset('assets/img/mark_closed.jpg') }}"></span>休業日</dd>
  362. <!-- //// ++++ #calender_titleArea ++++ //// -->
  363. </dl>
  364. <!-- // △△ カレンダー ++ △△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△ -->
  365. <ul
  366. id="calenderList">
  367. <!-- ■■ ++ ONE CALENDER ++ ■■ -->
  368. <li class="one_calender">
  369. <h5 class="calender_month">2024年xx月</h5>
  370. <table class="calender_table">
  371. <tbody>
  372. <tr class="title_week">
  373. <th>日</th>
  374. <th>月</th>
  375. <th>火</th>
  376. <th>水</th>
  377. <th>木</th>
  378. <th>金</th>
  379. <th>土</th>
  380. </tr>
  381. </tbody>
  382. </table>
  383. <!-- /// *** .calender_table *** /// -->
  384. </li>
  385. <!-- //// .one_calender **** //// -->
  386. <!-- ■■ ++ ONE CALENDER ++ ■■ -->
  387. <li class="one_calender">
  388. <h5 class="calender_month calender_next_month">2024年xx月</h5>
  389. <table class="calender_table calender_next_table">
  390. <tbody>
  391. <tr class="title_week">
  392. <th>日</th>
  393. <th>月</th>
  394. <th>火</th>
  395. <th>水</th>
  396. <th>木</th>
  397. <th>金</th>
  398. <th>土</th>
  399. </tr>
  400. </tbody>
  401. </table>
  402. <!-- /// *** .calender_table *** /// -->
  403. </li>
  404. <!-- //// .one_calender **** //// -->
  405. <!-- //// ++++ #calender_titleArea ++++ //// -->
  406. </ul>
  407. </div>
  408. </div>
  409. <!-- ///// #Calender +++++ ///// -->
  410. <!-- // ++ 発送日確認 ++ /////////////////////////////////////////////////////////////// -->
  411. <div id="Delivery" class="one_box fades">
  412. <form
  413. action="" class="input_content">
  414. <!-- // △△ カテゴリ ++ △△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△ -->
  415. <h3 class="section_title up">カテゴリを選択してください</h3>
  416. <ul id="detail_checkList" class="confirm fades">
  417. {% for category in categories %}
  418. <!-- ☆☆ ++ ステッカー ++ ☆☆ -->
  419. <li class="type_check up">
  420. <label><input type="radio" name="category" value="{{ category.id }}" class="form_check"/>
  421. <span>{{category.name}}</span>
  422. </label>
  423. </li>
  424. {% endfor %}
  425. </ul>
  426. <!-- //// ++++ .detail_checkList ++++ //// -->
  427. <!-- // △△ 商品 ++ △△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△ -->
  428. <h3 class="section_title up product-block" style="display: none">商品を選択してください</h3>
  429. <ul id="detail_checkList" class="product-block product-list confirm fades" style="display: none">
  430. </ul>
  431. <!-- //// ++++ .detail_checkList ++++ //// -->
  432. <!-- // △△ 発送日確認 ++ △△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△ -->
  433. {% set days = {'Mon': '月', 'Tue': '火', 'Wed': '水', 'Thu': '木', 'Fri': '金', 'Sat': '土', 'Sun': '日'} %}
  434. {% set bussiness_day = "now"|date("D") %}
  435. <div class="delivery_confirm" style="display: none">
  436. <h3 class="section_title up">発送日確認
  437. <p class="section_note up working-time">本日{{ "now"|date("Y年n月j日") }}({{ days[bussiness_day] }})』ご注文確定の場合、下記日程で発送いたします。</p>
  438. <p class="section_note up holiday-time"></p>
  439. </h3>
  440. <div id="tableBox" class="confirm fades">
  441. <table cellpadding="0" cellspacing="0" id="cart_indexTable" class="confirm fades">
  442. <tbody>
  443. <tr id="root-table">
  444. <th class="order_num">
  445. <p>枚数</p>
  446. </th>
  447. <th>
  448. <p>最安値</p>
  449. </th>
  450. <th class="line" colspan="3">
  451. <span></span>
  452. </th>
  453. <th>
  454. <p>最短納期</p>
  455. </th>
  456. </tr>
  457. </tbody>
  458. </table>
  459. <!-- //// ++++ #cart_indexTable ++++ //// -->
  460. <!-- //// ++++ #tableBox ++++ //// -->
  461. </div>
  462. <div class="table_info up">
  463. <span>大口注文はメールでお問い合わせください</span>
  464. </div>
  465. </div>
  466. <!-- //// .table_info **** //// -->
  467. {% if data.product is defined %}
  468. <a href="{{ url('detail_product', {id: data.product.id}) }}" style="text-decoration: none">
  469. <div id="btnSubmit" class="up"><input style="submit" name="submit" value="商品ページへ" class="btn_submit"></div>
  470. </a>
  471. {% endif %}
  472. <!-- // △△ データ作成上のご注意 ++ △△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△△ -->
  473. <aside class="one_box caution_box fades">
  474. <div class="caution_inner">
  475. <h5 class="caution_title up">データ作成上のご注意</h5>
  476. <p class="indent up">◯悪天候・天災及び年末年始は物流の混雑や交通渋滞の影響により1日程度の遅れが生じることがあります。</p>
  477. <p class="indent up">◯配送遅延につきましては当店では一切の責任を負いかねますのであらかじめご了承ください。</p>
  478. <!-- // ** .caution_box ** // -->
  479. </div>
  480. </aside>
  481. </form>
  482. </div>
  483. <!-- ///// #Delivery +++++ ///// -->
  484. <!-- // ++ 店頭引取について ++ /////////////////////////////////////////////////////////////// -->
  485. <dl id="Store" class="one_box">
  486. <dt id="storeLeft">
  487. <article class="one_group">
  488. <h3 class="section_title up">店頭引取について</h3>
  489. <h4 class="guide_headline fades">本社/FACTO_OSAKA [大阪・江坂]</h4>
  490. <p class="flow_notes indent up">◯ 商品お受取時店頭支払(現金・クレジットカード・PayPay・au PAY)</p>
  491. <p class="flow_notes indent up">◯ 店頭引取をご希望の場合は、完成予定日の翌営業日11時からお引取可能。事前のご予約にご協力ください</p>
  492. <!-- //// **** .one_group **** //// -->
  493. </article>
  494. <article class="one_group">
  495. <h4 class="guide_headline fades">アクセスマップ</h4>
  496. <p class="flow_notes up">〒564-0051 大阪府吹田市豊津町21-10 クルーズ江坂第二ビル2F<br>
  497. <span class="nolink">tel 06-6384-8422</span><br>
  498. 営業時間:11:00〜18:00</p>
  499. <!-- //// **** .one_group **** //// -->
  500. </article>
  501. </dt>
  502. <!-- //// +++ #storeLeft ++++ //// -->
  503. <dd id="storeRight">
  504. <figure id="payment-accessMap" class="up">
  505. <iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3277.868877398006!2d135.4902870757471!3d34.75889572289904!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x6000e5b6f9ba168b%3A0x3185ef8a686677c2!2sFACTO_OSAKA!5e0!3m2!1sja!2sjp!4v1713609119019!5m2!1sja!2sjp" width="600" height="450" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
  506. <!-- //// #payment-accessMap ++++ //// -->
  507. </figure>
  508. </dd>
  509. <!-- //// +++ #storeRight ++++ //// -->
  510. <!-- ///// #Store +++++ ///// -->
  511. </dl>
  512. </section>
  513. <!-- ///// +++++ #Delivery +++++ ///// -->
  514. <!-- ///// +++++ #mainContents +++++ ///// -->
  515. </main>
  516. <!-- // ++ パンクズ ++ //////////////////////////////////////////////////////////// // -->
  517. <div id="bread_crumbBloc" class="fades">
  518. <ul id="breadCrumb" class="fades">
  519. <li class="up">
  520. <a href="/"><img src="{{ asset('assets/img/icon_home.png') }}" alt="ホーム"></a>
  521. </li>
  522. <li class="up">納期・発送日確認</li>
  523. </ul>
  524. <!-- ///// #breadCrumb +++++ ///// -->
  525. <!-- ///// +++++ #bread_crumbBloc +++++ ///// -->
  526. </div>
  527. {% endblock %}