スーパーの店員がChatGPTに質問２つで「賞味期限管理アプリ」を作ってみた

# 😏ChatGPTさんと仲良くなろう！
ちょっと前に`ChatGPT`がニュースで話題になり
デジタル初心者の私には`ChatGPT`はネガティブイメージ💦
なんか使ったら後ろめたいような、いけないような。。。

一方、使いこなすとかっこいいよねー✨
最先端じゃない？というポジティブイメージ🔅もありつつ手を出さずにいたツール。
一大決心をし、使ってみることに。
一緒に3つの事にチャレンジ🎶

★今回使用したツール★
・[ChatGPT](https://chat.openai.com/auth/login)
・[CodePen](https://codepen.io)
・[LINE Deveropers](https://account.line.biz/login)
・[Make](https://www.make.com/en)

## 😏定番の疑似彼氏LINE Botで作ってみる
毎日の通勤は片道50キロの車の運転💦
家に帰れば小学生２人と２歳児の子供３人ワンオペ育児と
毎日がバタバタと過ぎていく日々
とにかく癒しが欲しい！！

`ChatGPT`に設定をかけるとLINE Botがカスタマイズ出来ると聞いた！
`ChatGPT`の導入として暖かい言葉をくれるLINE Bot作成に挑戦✨



`make`を使って💕癒しの彼氏💕できちゃった👍

![IMG_3442.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/324d5130-dcb8-be49-07a4-e358677755f8.png)

・`make`でLINEのおうむ返しBot作成後、Open AIモジュールを追加
＜設定はこんな感じ＞
![スクリーンショット 2023-08-16 152242.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/7e24ebe4-6db4-d76f-9110-c1180915933e.png)

ほんとに優しさで溢れている💫
なんだかちょっと恥ずかしくなってくるなぁ



これが出来たらなんだかもっとできるような気がしてきた！
コードがかけなくてもGPTさんが書いてくれるというので
前から作りたかった賞味期限の管理＆値引きアプリを`ChatGPT`と`codepen`でチャレンジ！
## 😏賞味期限の管理＆値引きアプリの作成

私はGMSの食品売場で働いている。
自社では賞味期限に対して、
値引き開始してもよい日を「販売検討日」とし、
商品を売場撤去しなければならない日を「販売限度日」と設定している。
「販売検討日」から「販売限度日」の間に商品を売り切らなければならない。
ある商品に対して値引きすべきかどうかを担当者がその日、即席で早見表を作ったり
指折り数えたりして判断するのをよく目にするので、一目でわかるようなものが出来ないかなぁ
と以前から思っていた。

※ChatGPTさんに以下のように相談した


:::note warm
自社は食品販売を行っている。
賞味期限に対して値引きを開始する日を販売検討日という。
賞味期限前に販売を終了する日を販売限度日という。
販売検討日、販売限度日ともに販売する商品に対して一定のルールがある。
例えば乾物などは3か月前に検討日に入り、1か月前を限度日とする。
ハムなどは10日前に検討日とし、5日前を限度日とする。
そこで賞味期限を入力したら、検討日、限度日のサイクルを入力し、自動計算で検討日、限度日をわかるアプリを`codepen`で作成したい。
また、価格を入力して1割引き、2割引き、3割引き、4割引き、半額を自動計算してほしい。
初心者なのでコードを作ってもらえますか？
:::
★GPTさんからの返答
>もちろんです！以下が、賞味期限に基づいて販売検討日と販売限度日を計算し、また価格を割引するためのJavaScriptコード例です。コードペンにコードを貼り付けて実行することで、希望通りのアプリを作成できます。
>以下のコードは、賞味期限、検討日サイクル、限度日サイクル、および価格割引を計算する簡単なアプリです。この例は基本的な動作を示すものであり、実際のアプリに組み込む際にはさらなる機能やエラーチェックを追加することができます。



<details>
<summary>GPTさんにかいてもらったコード</summary></div>

```HTML
```<!DOCTYPE html>
<html>
<head>
  <title>賞味期限アプリ</title>
</head>
<body>
  <h2>賞味期限計算アプリ</h2>
  <label for="expirationDate">賞味期限：</label>
  <input type="date" id="expirationDate">
  <br>
  <label for="considerationCycle">検討日サイクル（日）：</label>
  <input type="number" id="considerationCycle">
  <br>
  <label for="limitCycle">限度日サイクル（日）：</label>
  <input type="number" id="limitCycle">
  <br>
  <label for="originalPrice">元の価格：</label>
  <input type="number" id="originalPrice">
  <br>
  <button onclick="calculate()">計算</button>
  <br>
  <h3>結果：</h3>
  <p id="result"></p>

  <script>
    function calculate() {
      const expirationDate = new Date(document.getElementById('expirationDate').value);
      const considerationCycle = parseInt(document.getElementById('considerationCycle').value);
      const limitCycle = parseInt(document.getElementById('limitCycle').value);
      const originalPrice = parseFloat(document.getElementById('originalPrice').value);

      const today = new Date();
      const considerationDate = new Date(expirationDate);
      considerationDate.setDate(expirationDate.getDate() - considerationCycle);
      const limitDate = new Date(expirationDate);
      limitDate.setDate(expirationDate.getDate() - limitCycle);

      let discountPrices = [];

      for (let discountRate = 0.1; discountRate <= 0.5; discountRate += 0.1) {
        const discountedPrice = originalPrice * (1 - discountRate);
        discountPrices.push(discountedPrice);
      }

      const result = `
        販売検討日: ${considerationDate.toLocaleDateString()}
        販売限度日: ${limitDate.toLocaleDateString()}
        価格割引:
        1割引: ${discountPrices[0].toFixed(2)}円
        2割引: ${discountPrices[1].toFixed(2)}円
        3割引: ${discountPrices[2].toFixed(2)}円
        4割引: ${discountPrices[3].toFixed(2)}円
        半額: ${discountPrices[4].toFixed(2)}円
      `;

      document.getElementById('result').textContent = result;
    }
  </script>
</body>
</html>
```

</div>
</details>
★GPTさんからの返答

>このコードをコードペンなどに貼り付けて実行すると、賞味期限、検討日サイクル、限度日サイクル、元の価格を入力し、「計算」ボタンをクリックすると計算結果が表示されるアプリが作成されます。初心者向けに簡単な例として提供していますが、必要に応じてさらなる機能やデザインのカスタマイズを行ってください。



### ①最初に出来たもの
![スクリーンショット 2023-08-16 200300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/d532d302-42d1-5647-cf9d-87c5bafe7521.png)

`計算をクリック`
![スクリーンショット 2023-08-16 164952.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/65ed20b8-f564-ff64-9fe9-3c4e935997fc.png)
### 上記画像の改善を依頼

※さらにお願いをする

:::note warm
価格は直接入力したほうが早いので直接入力に変更してください。
割引表示を横並びではなく縦一行ずつにしてほしいです。
:::


<details>
<summary>GPTさんにかいてもらったコード（すべて置き換え）</summary></div>

```HTML
```<!DOCTYPE html>
<html>
<head>
  <title>賞味期限アプリ</title>
</head>
<body>
  <h2>賞味期限計算アプリ</h2>
  <label for="expirationDate">賞味期限：</label>
  <input type="date" id="expirationDate">
  <br>
  <label for="considerationCycle">検討日サイクル（日）：</label>
  <input type="number" id="considerationCycle">
  <br>
  <label for="limitCycle">限度日サイクル（日）：</label>
  <input type="number" id="limitCycle">
  <br>
  <label for="originalPrice">元の価格：</label>
  <input type="number" id="originalPrice">
  <br>
  <button onclick="calculate()">計算</button>
  <br>
  <h3>結果：</h3>
  <p id="result"></p>

  <script>
    function calculate() {
      const expirationDate = new Date(document.getElementById('expirationDate').value);
      const considerationCycle = parseInt(document.getElementById('considerationCycle').value);
      const limitCycle = parseInt(document.getElementById('limitCycle').value);
      const originalPrice = parseFloat(document.getElementById('originalPrice').value);

      const today = new Date();
      const considerationDate = new Date(expirationDate);
      considerationDate.setDate(expirationDate.getDate() - considerationCycle);
      const limitDate = new Date(expirationDate);
      limitDate.setDate(expirationDate.getDate() - limitCycle);

      let discountPrices = [];

      for (let discountRate = 0.1; discountRate <= 0.5; discountRate += 0.1) {
        const discountedPrice = originalPrice * (1 - discountRate);
        discountPrices.push(discountedPrice);
      }

      const result = `
        販売検討日: ${considerationDate.toLocaleDateString()}
        販売限度日: ${limitDate.toLocaleDateString()}
        <br>価格割引:
        <br>1割引: ${discountPrices[0].toFixed(2)}円
        <br>2割引: ${discountPrices[1].toFixed(2)}円
        <br>3割引: ${discountPrices[2].toFixed(2)}円
        <br>4割引: ${discountPrices[3].toFixed(2)}円
        <br>半額: ${discountPrices[4].toFixed(2)}円
      `;

      document.getElementById('result').innerHTML = result;
    }
  </script>
</body>
</html>
```
</div>
</details>

★GPTさんからの返答
>このコードを使用して、直接価格を入力し、割引表示が縦に並ぶ賞味期限アプリを作成できます。必要に応じてデザインや機能を調整してください。

### ②次にできたもの


![スクリーンショット 2023-08-16 165554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/d04a7b30-57e3-c749-57bc-ca7f8917b866.png)

※価格は直接入力出来ないままでした💦
見比べるとコードが変わっていなかった😨
しかし、イメージ通りではある。



## 😏お客さまからの注文管理アプリ作成

質問２つで大まかなものができたので余った時間で
先日`Glide`で作ったアプリと同様の仕様のものが出来ないかチャレンジすることに

先日`Glide`で作ったアプリの内容はこちらの記事をご覧ください。

https://qiita.com/Nonokouyu/items/5ffcfd90d8b9d530f478

出来上がりがこちら

https://twitter.com/nonokoyu0606/status/1691878549706387501?s=20



※まずはGPTさんに相談
~new chat~

:::note warm
自社はスーパーマーケットです。
お客さまからの注文を受けることを客注といいます。
客注を受ける際に、受けたサービスカウンターと各売場担当者との伝達ツールをcodepenで作ったアプリで行いたいです。
・お客さまの名前
・商品名
・数量
・部門
・受付日
・入荷予定日
・受付担当者
・受付ステータス
・備考欄
を含めたものを作りたいのですがコードの作成は可能でしょうか?
初心者でもわかるように教えてもらえますか？
:::
★GPTさんからの返答
>もちろんです！お手伝いできることは喜んで行います。ただし、完全なアプリケーションのコードを提供するのは難しいですが、基本的なステップとコード例を提供いたしますので、それを元にアプリケーションを構築していく手助けができればと思います。

>まず、HTML、CSS、JavaScriptを使用して基本的なフォームを作成してみましょう。以下は、ご希望の情報を収集するための簡単なフォームの例です。

<details>
<summary>GPTさんにかいてもらったコード</summary></div>
index.html（HTMLファイル）

```HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>客注受付アプリ</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <h1>客注受付アプリ</h1>
  <form id="orderForm">
    <label for="customerName">お客さまの名前:</label>
    <input type="text" id="customerName" required><br>
    
    <label for="productName">商品名:</label>
    <input type="text" id="productName" required><br>
    
    <label for="quantity">数量:</label>
    <input type="number" id="quantity" required><br>
    
    <label for="department">部門:</label>
    <input type="text" id="department" required><br>
    
    <label for="orderDate">受付日:</label>
    <input type="date" id="orderDate" required><br>
    
    <label for="expectedArrival">入荷予定日:</label>
    <input type="date" id="expectedArrival" required><br>
    
    <label for="assignedStaff">受付担当者:</label>
    <input type="text" id="assignedStaff" required><br>
    
    <label for="status">受付ステータス:</label>
    <select id="status" required>
      <option value="未処理">未処理</option>
      <option value="処理中">処理中</option>
      <option value="完了">完了</option>
    </select><br>
    
    <label for="notes">備考欄:</label>
    <textarea id="notes"></textarea><br>
    
    <button type="submit">注文を受ける</button>
  </form>
  
  <script src="script.js"></script>
</body>
</html>
```
styles.css（CSSファイル）

```css
body {
  font-family: Arial, sans-serif;
  margin: 20px;
}

form {
  border: 1px solid #ccc;
  padding: 20px;
  border-radius: 5px;
}

label {
  font-weight: bold;
}

input[type="text"],
input[type="number"],
input[type="date"],
select,
textarea {
  width: 100%;
  padding: 5px;
  margin-bottom: 10px;
}

button {
  padding: 10px 20px;
  background-color: #007bff;
  color: #fff;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}
```
script.js（JavaScriptファイル）
```jS
document.getElementById('orderForm').addEventListener('submit', function (event) {
  event.preventDefault();

  const customerName = document.getElementById('customerName').value;
  const productName = document.getElementById('productName').value;
  const quantity = document.getElementById('quantity').value;
  const department = document.getElementById('department').value;
  const orderDate = document.getElementById('orderDate').value;
  const expectedArrival = document.getElementById('expectedArrival').value;
  const assignedStaff = document.getElementById('assignedStaff').value;
  const status = document.getElementById('status').value;
  const notes = document.getElementById('notes').value;

  // ここでデータを保存または送信する処理を追加する
  // 例: API呼び出し、データベースへの保存など
});
```
</div>
</details>

※さらにお願いをする

:::note warm
部門を農産、水産、畜産、デリカ、グロサリー、デイリーに設定してください。
ステータスを追加し、確認済み、発注済み、入荷済み、連絡済みとしてください。
スプレッドシートと紐づけできますか？
:::
★GPTさんからの返答
>このコードは、基本的なフォームを作成し、フォームの送信イベントをキャッチして、フォーム内の値をJavaScriptで取得する方法を示しています。実際のアプリケーションでは、データを保存するためのサーバーサイドの処理を追加する必要があります。データをデータベースに保存したり、APIを呼び出したりすることで、情報を管理することができます。

>このコードを元に、必要に応じてカスタマイズや機能の追加を行いながら、お客さまの注文を受けるアプリケーションを作成していくことができます。初心者でも理解しやすいように、基本的な構造とアイディアを提供しましたが、実際のアプリケーションはより多くの要素を考慮する必要があることに注意してください。
<details>
<summary>GPTさんにかいてもらった追加コード
（これを該当箇所のみ置き換え）</summary></div>


部門とステータスの追加:
既存の <select> 要素と <option> 要素を、新しい部門とステータスのオプションで更新します。

index.html（一部の変更を示します）
```HTML
<!-- 部門の選択肢を更新 -->
<label for="department">部門:</label>
<select id="department" required>
  <option value="農産">農産</option>
  <option value="水産">水産</option>
  <option value="畜産">畜産</option>
  <option value="デリカ">デリカ</option>
  <option value="グロサリー">グロサリー</option>
  <option value="デイリー">デイリー</option>
</select><br>

<!-- ステータスの選択肢を更新 -->
<label for="status">受付ステータス:</label>
<select id="status" required>
  <option value="未処理">未処理</option>
  <option value="確認済み">確認済み</option>
  <option value="発注済み">発注済み</option>
  <option value="入荷済み">入荷済み</option>
  <option value="連絡済み">連絡済み</option>
</select><br>
```
>スプレッドシートとの連携:
JavaScriptを使用して、フォームのデータをスプレッドシートに送信する方法を説明します。Google Sheets API を使用してスプレッドシートにデータを書き込むことができますが、ここでは簡単な例として SheetDB というウェブサービスを使用します。SheetDB を使用すると、Googleアカウントなしでスプレッドシートと連携できます。

script.js（一部の変更を示します）
```JS
</div>
</details>

document.getElementById('orderForm').addEventListener('submit', function (event) {
  event.preventDefault();

  // フォームのデータを取得
  const customerName = document.getElementById('customerName').value;
  const productName = document.getElementById('productName').value;
  const quantity = document.getElementById('quantity').value;
  const department = document.getElementById('department').value;
  const orderDate = document.getElementById('orderDate').value;
  const expectedArrival = document.getElementById('expectedArrival').value;
  const assignedStaff = document.getElementById('assignedStaff').value;
  const status = document.getElementById('status').value;
  const notes = document.getElementById('notes').value;

  // SheetDBにデータを送信
  fetch('https://sheetdb.io/api/v1/YOUR_SHEET_ID', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      data: {
        customerName,
        productName,
        quantity,
        department,
        orderDate,
        expectedArrival,
        assignedStaff,
        status,
        notes,
      },
    }),
  })
  .then(response => response.json())
  .then(data => {
    // データが正常に送信された場合の処理
    alert('注文が送信されました。');
    // フォームをリセット
    document.getElementById('orderForm').reset();
  })
  .catch(error => {
    // エラーが発生した場合の処理
    alert('エラーが発生しました。もう一度お試しください。');
    console.error(error);
  });
});
```
</div>
</details>

★GPTさんからの返答
>このコードでは、SheetDB のエンドポイントに対してPOSTリクエストを送信し、フォームのデータをスプレッドシートに追加しています。YOUR_SHEET_ID を実際のシートIDに置き換えてください。また、fetch() 内のURLを適切に設定してください。

>これで、部門とステータスを追加し、スプレッドシートとの連携も実装された客注受付アプリが完成します。ただし、セキュリティやエラーハンドリングなど、実際のアプリにはもっと多くの要素を考慮する必要があることに留意してください。

・YOUR_SHEET_IDはこれでいいのかな？
![スクリーンショット 2023-08-17 042715.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/1ac02190-1050-f9f3-872d-69624e3c5e34.png)


※わかったようなわからないような、またまた聞いてみる

:::note warm
fetch() 内のURLを適切に設定を具体的に教えてください
:::
★GPTさんからの返答
>もちろんです。以下に具体的な手順を示します。

>SheetDB のセットアップ:
>まず、SheetDB のウェブサイト（https://sheetdb.io/）にアクセスし、アカウントを作成します。

＜アカウント作成＞
![スクリーンショット 2023-08-17 023922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/77b6ef67-9b2c-7fc2-2ef0-12dad7885fc5.png)



>新しいスプレッドシートの作成:

>SheetDB のダッシュボードにアクセスして、新しいスプレッドシートを作成します。作成したスプレッドシートには自動的にユニークな id 列が追加されます。

>＜API エンドポイントの取得＞
![ID.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458430/3bfce60a-3990-49f9-9dec-f73a60033b13.png)

>SheetDB のダッシュボードで作成したスプレッドシートを選択し、API タブに移動します。API エンドポイントが表示されるので、その URL をコピーします。

>JavaScript コードの更新:

>先ほど提供した script.js 内の fetch() の URL 部分を、コピーした API エンドポイントに置き換えます。




>注意事項:
>上記のコードで YOUR_SHEETDB_API_URL を sheetDbApiUrl に置き換えてください。
API エンドポイントの形式は https://sheetdb.io/api/v1/YOUR_SHEET_ID のようなものです。YOUR_SHEET_ID 部分を自分のスプレッドシートのIDに置き換えてください。
これで、SheetDB を使用してフォームデータをスプレッドシートに送信できるようになります。正しく設定された API エンドポイントを使用して、データがスプレッドシートに追加されることを確認してください。


以上で完成！！
ここまでが動画の内容だけれど、スプレッドシートと連動しない。
データは正常に送信されてエラー表示もないのに。
スプレッドシートに記述されなかった。

`Glide`で作ったアプリの方が実用的だったけど
GPTさんはコードが書けなくても書いてくれるし、親切に説明もしてくれる。
これからも色々なツールを場面に合わせてうまく使えるようになるべく頑張ります。

## 🎆ありがとう　GPTさん

GPTさん優しく教えてくるし、親切だし最高だね！
たまに間違うところもかわいい✨✨
私の性格を知ってか、頼りすぎるなと遠回しに念を押されている気がする箇所が何個か・・・
『実際のアプリにはもっと多くの要素を考慮する必要があることに留意してください。』
この言い回し何回出てきたことか。
親しみを込めてさんづけでよぶことにした
今まで使ってなくてごめんね😓

気を付けたことは箇条書きにすることと
質問回数を少なくすること
これは質問9回くらいでGPTさんの内容が無料プランではリセットされるとなにかで読んだから。
実際はわかりません。
GPTさんと少し仲良くなれました💕