Lwcでその日訪問予定の取引先をマップに表示する


営業支援ツールに関しては、標準オブジェクトでほとんど事足りるsalesforce。
さらに、その日訪問予定の顧客取得し、地図上にマッピングして...
あれ、ホントにこの機能って必要なのかな。
営業したことないから分かりかねますが、
これができれば「LWCで任意の関連レコードとってきて表示させる」
という汎用的な機能のベースになると思って頑張ります。

コードについては株式会社テラスカイ様の
「TerraSkyBase　～テラスカイを支える人とテクノロジーの情報を発信する基地局～」
を参考に（ほぼ拝借して）そこに付け加える形で作成していきます。

https://base.terrasky.co.jp/articles/58My1

# アジェンダ
* 概要
* ApexClassでレコードを取得
* HTML
* JavaScript
* js-meta.xml
* 今後の課題

# 概要
やりたいことととしては冒頭でも触れている通り、
「今日訪問予定の顧客情報を地図へマッピングしたい」です。

ユーザ目線では、
カレンダーに予定を作成すると
![creative-raccoon-vkbfxx-dev-ed.lightning.force.com_lightning_o_Event_home (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115033/3316c2bc-dfd6-d6b4-a9f8-6f321691cf9d.png)
マップに表示されるようになります。
![creative-raccoon-vkbfxx-dev-ed.lightning.force.com_lightning_n_accountMapExample (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115033/f89c967e-c97a-1a42-70fc-be82a504ab40.png)


より具体的に説明すると、「行動（Event）オブジェクトの開始日（startDateTime）項目が“今日の日付と一致する”レコードの
関連先（What）項目に紐づいている取引先（Account）レコードの情報を取得し、地図コンポーネントを使用して
googleMap上に取得した顧客の住所にピンを打つこと」が今回の目的です。

#ApexClassでレコード取得
はじめにApexClassのなかでSOQLを使用し、必要なレコードを取得します。
関連レコードの取得方法を調べるといろいろ出てきますが、下記のコードを参考にしてください。

```apex
pubulic with sharing class getTodayAcc
 @auraEnabled(cacheable=true)
 public static List<Event> getAcc(){
   return[
     SELECT AccountId, Account.Name, Account.BillingCountry, Account.BillingState, 
            Account.BillingCity, Account.BillingStreet, Account.Description
            
            ​//カスタム項目の場合は、下記のように項目名__cと記述してください。
            //Account.Prefecture__c,Account.City__c

     FROM Event
     WHERE StartDateTime = Today and What.Type IN ('Account')
     ORDER BY StartDateTime 
   ];
 }
}
```

#HTML
次にHTMLを記述します。
テラスカイ様のコードに加えて「zoom-level={zoomLevel}」を記述します。

タグの属性と仕様についてはこちら

https://developer.salesforce.com/docs/component-library/bundle/lightning-map/documentation

```HTML
<template>
    <lightning-map
        map-markers={mapMarkers}
        selected-marker-value={selectedMarkerValue}
        markers-title="Today's account list"
        onmarkerselect={handleMarkerSelect}
        zoom-level={zoomLevel}
        list-view="auto">
    </lightning-map>
</template>
```
#Javascript
こちらもベースのコードはテラスカイ様より拝借。
加えてHTMLに記述したzoom-levelを指定します。

今日の訪問予定が一件の場合、zoom-levelが未指定だと、マッピング時に自動的に最大ズームされてしまいます。
なので、訪問予定一件（＝Eventから取得したレコードが一件）のとき、Zoom-levelを任意の値にセットします。

```javascript
import { LightningElement, track, wire } from 'lwc';

// getAccounts メソッドのインポート
import getAccounts from '@salesforce/apex/LightningMapExampleController.getAccounts';

export default class LightningMapExample extends LightningElement {
    // 表示するマーカーのリスト
    @track
    mapMarkers=[];

    // 選択しているマーカーの値
    @track
    selectedMarkerValue;
    
    // 取引先を取得して表示するマーカーを作成
    @wire(getAccounts, {})
    wiredAccounts({ data }) {
        if (data) {
            var markers = [];
            for(var i = 0; i < data.length; i++){
                var acc = data[i];
                markers.push({
                    location: {
                        Country : acc.Account.BillingCountry,
                        State : acc.Account.BillingState,
                        City: acc.Account.BillingCity,
                        Street: acc.Account.BillingStreet
                    },
                    icon : "standard:account",
                    
                    //selectedMarkerValueへ設定される
                    value: acc.AccountId,

                    //マーカークリック時に表示される情報
                    title: acc.Account.Name,
                    description: acc.Description 
                });
            }

            //取得した顧客情報レコードが一つのとき、zoom-Levelを指定します。
            if(data.length == 1){
               this.zoomLevel = 13;
            }
            this.mapMarkers = markers;
        }    
    }  ![Something went wrong]()


    // マーカー選択時のアクション
    handleMarkerSelect(event) {
        console.log(event.target.selectedMarkerValue);
    }
}
```
# js-meta.xml
最後にメタデータを設定します。
isExposedはデフォルトではFalseですが、Trueにしないとカスタムコンポーネントとして使用できません。（編集画面に表示されません）
Tragetで、使用するアプリケーションページを指定します。

```Html
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
```

#今後の課題
① レンダリング
　皆様お気づきかと思いますが、カレンダーへ予定を作成後、タブを切り替えただけでは
　その予定に紐づく顧客が表示されません。毎回ページの再読み込みを手動で行うのは
　イケていませんね！
　
② 条件をいろいろ選べるようにしたい
　といいますのも、きっと一週間以上訪問していない顧客や、売上が高い顧客など、
　何かしら目的をもって訪問すると思いますので、そういった条件でも絞り込めると
　より使いこなしてくれるのではないでしょうか。知らんけど。

③ 自分の現在位置　
　これは言わずもがなですね。すぐに実装できるよう引き続き勉強します。

次回は上記の課題に対する記事を書く予定です！