Dynamics365 Sales 데이터를 .NET 응용 프로그램으로 가져오고 분석하는 방법 > 블로그 & Tips

본문 바로가기

ComponentOne

블로그 & Tips

Dynamics365 Sales 데이터를 .NET 응용 프로그램으로 가져오고 분석하는 방법

페이지 정보

작성자 GrapeCity 작성일 21-10-21 14:58 조회 910회 댓글 0건

본문

첨부파일

Dynamics 365 Sales는 조직에서 영업 프로세스 등을 관리할 수 있게 해주는 고객 관계 관리 응용 프로그램(CRM)입니다. 응용 프로그램 자체도 보고 및 데이터 분석을 위한 여러 기능을 제공하지만 보고와 분석을 비롯한 다양한 목적으로 외부 응용 프로그램을 만들어야 하는 경우도 있습니다. 이 경우를 위해 Dynamics 365는 외부 응용 프로그램이 데이터를 가져오기 위해 액세스할 수 있는 서비스를 제공합니다. 이 블로그에서는 DataConnectors, DateEngine 같은 ComponentOne DataServices 라이브러리를 사용하여 데이터를 가져오고 메모리 내 분석을 수행하는 방법을 살펴보겠습니다.

DataConnectors에 대한 자세한 내용은 여기를 참조하십시오.


비즈니스 사용 사례

이 데모에서는 .NET 응용 프로그램에서 Dynamics 365 Sales 기회 데이터를 분석하여 다음을 찾으려고 합니다.

  • 각 영업 단계의 기회

  • 각 제품의 열린 기회

  • 각 영업 담당자 버킷의 기회 값

  • 각 회계 분기의 기회


프로젝트 설정

위의 정보를 파악하려면 기회 엔터티(Oppurtunity EntityType)의 다음 필드가 필요합니다.

  • owner

  • createdon

  • stagename

  • quantity

  • extendedamount

  • productname

위 데이터는 개별 엔터티에 매핑된 경우가 많습니다. 예를 들어, Opportunities 표에는 salesrep의 이름 대신 ownerid의 GUID가 있고 salesrep의 실제 이름은 다른 systemsuser 표에 있을 수 있습니다. 따라서 데이터를 얻기 위해 사용자가 여러 표에서 데이터를 가져와야 할 수 있으므로 복잡해질 수 있습니다. 이 경우 ComponentOne DataConnectors를 사용하면 시간을 절약할 수 있습니다. 데이터 커넥터를 통해 사용자가 ADO.NET에서 SQL을 사용하거나 LINQ와 EntityFramework Core를 사용하여 데이터를 가져오고 쿼리할 수 있기 때문입니다. 이 블로그에서는 Dynamics 365 Sales ADO.NET 클래스와 SQL JOIN 쿼리를 사용하여 여러 표에서 원하는 데이터를 가져올 것입니다. 

데이터를 사용할 수 있게 되면 원하는 결과를 얻기 위해 C1DataEngine과 C1PivotEngine을 사용하여 메모리 내 피벗을 만듭니다. 먼저 WinForms 응용 프로그램을 만들고 다음 NuGet 패키지를 추가합니다.

  • C1.AdoNet.D365

  • C1.DataEngine

  • C1.PivotEngine


Dynamics 365 Sales에서 데이터 가져오기

PivotService라는 클래스를 추가하고 C1DataEngine WorkSpace에 대해 public 속성을 선언합니다. Dynamics 365 Sales에서 데이터를 가져올 GetData() 메서드를 추가합니다.

class PivotService
  {
    private Workspace ws;
    public Workspace Workspace => ws;
    private dynamic opportunity;
    private readonly string QueryName = "BaseQuery";
    public C1PivotEngine engine;
​
  private string GetD365SConnection()
    {
      var config = Properties.Settings.Default;
      string extendProperties = "{\"resource\":\"" + config.Resource + "\"}";
      string conectionStr = $@"Url={config.UrlDynamics};Use Etag=true;OAuth Client Id={config.ClientID};OAuth Client Secret={config.ClientSecret};OAuth Token Endpoint={config.TokenEndpoint};OAuth Extend Properties={extendProperties}";
​
      return conectionStr;
    }
​
​
​
    public void GetData()
    {
      C1.AdoNet.D365S.C1D365SConnection con = new C1.AdoNet.D365S.C1D365SConnection(GetD365SConnection());
      con.Open();
​
      string sql = "select op.opportunityid, op.name, op._ownerid_value,op.createdon, op._parentaccountid_value,op.estimatedclosedate, op._parentcontactid_value, osp._activestageid_value, gc_renewaldate, gc_paymenttermscode, gc_opportunitytype, p.productnumber, p.name as productname, p.gc_salesedition, ps.stagename, opp.priceperunit, opp.quantity, opp.extendedamount, su.fullname as salesrep from opportunities op inner join opportunityproducts opp on opp._opportunityid_value = op.opportunityid inner join opportunitysalesprocesses osp on osp._opportunityid_value = op.opportunityid inner join products p on p.productid = opp._productid_value inner join accounts a on a.accountid = op._parentaccountid_value and a.name like 'account%' inner join processstages ps on ps.processstageid = osp._activestageid_value inner join systemusers su on su.systemuserid = op._ownerid_value LIMIT 105";
​
      var cmd = new C1.AdoNet.D365S.C1D365SCommand(con, sql);
      var connector = new DbConnector(this.ws, con, cmd);
      connector.GetData("Opportunities");
​
    }
​
}


여기서는 C1D365SConnection 및 C1D365SCommand 인스턴스를 만들고 SQL 쿼리와 명령 개체 연결을 할당했습니다. 마지막으로, 데이터를 DataEngine 작업 영역으로 가져오는 명령을 실행하는 DbConnector 개체가 사용되었습니다. 결과에 Opportunities라는 이름이 지정되었습니다.


DataEngine 구성

다음에는 가져온 데이터에서 필요한 열을 가져오는 기본 쿼리를 정의합니다. 메모리에서 이 쿼리를 사용하여 데이터에 추가 변환을 적용할 수 있습니다. PivotService 클래스의 Init() 메서드에서 이 쿼리를 만듭니다. 또한 인스턴스를 DataEngine 작업 영역에 연결하여 기본 쿼리에 대한 피벗 변환을 만들 수 있도록 C1PivotEngine 인스턴스를 선언합니다.

DataEngine Configuration 확장 소스:

public PivotService()
      {
          Init();
      }
​
private void Init()
      {
          this.ws = new Workspace();
          this.ws.Init("workspace");
​
          //Import data if Opportunities table is null or data is stale in workspace
          if (Properties.Settings.Default.threshhold.Date < DateTime.Now.Date )
          {
              if (this.ws.GetTableData("Opportunities") == null)
              {
                  this.GetData();
                  Properties.Settings.Default["threshhold"] = DateTime.Now.Date;
                  Properties.Settings.Default.Save();
            }            
          }
​
          this.opportunity = this.ws.table("Opportunities");
​
          if (this.opportunity!=null)
          {
              var queryName = this.QueryName;
​
// create base query and execute it
              var settings = new
              {
                  opportunity.stagename,
                  opportunity.salesrep,
                  opportunity.createdon,
                  opportunity.productname,
                  opportunity.extendedamount,
                  Sales = Op.Sum(opportunity.extendedamount),
                  Quantity = Op.Count(opportunity.quantity),
                  QuantityTotal = Op.Sum(opportunity.quantity)
              };
​
              dynamic query = this.ws.query(queryName, settings);
              query.Query.Execute();
​
            //initialize pivotengine and connect workspace & base query
              this.engine = new C1PivotEngine();
              this.engine.Workspace = this.ws;
              this.engine.ConnectDataEngine(queryName);
        }            
      }


피벗 변환을 여러 개 만들고 반복 코드를 피하려고 하므로 여러 변환 쿼리의 피벗 필드를 전달하고 필드를 기준으로 피벗된 데이터를 반환하는 메서드를 만듭니다.

private C1PivotEngine CreateFlexPivotEngine(string queryName, string[] colFields, string[] rowFields, string[] valFields)
    {
      var fp = this.engine;
      fp.BeginUpdate();
      this.engine.ColumnFields.Clear();
      this.engine.RowFields.Clear();
      this.engine.ValueFields.Clear();
      fp.ColumnFields.Add(colFields);
      fp.RowFields.Add(rowFields);
      fp.ValueFields.Add(valFields);
      fp.EndUpdate();
      return fp;
    }


피벗 변환

이제 Dynamics365 서버에서 가져온 데이터에 대한 피벗을 만들고 각 변환을 위한 메서드를 만들 준비가 되었습니다. 메서드에 있는 위 'CreateFlexPivotEngine" 함수에 행, 열, 값 필드를 전달하여 해당 필드로 피벗을 만들고 pivotengine 객체를 반환합니다.


각 영업 단계의 기회

다음에는 각 영업 단계의 기회 값을 확인하려고 합니다. 이렇게 하려면 기본 쿼리의 stagename 및 sales 필드를 피벗합니다.

public IBindingList OpportunityByStage()
    {
      var fp = this.CreateFlexPivotEngine(this.QueryName, new string[] { "" }, new string[] { "stagename" }, new string[] { "Sales" });
      return fp.PivotDefaultView;
    }


다음 결과를 얻게 됩니다.

image1


각 제품의 열린 기회

제품 전체의 열린 기회를 확인하려면 기본 쿼리에서 productname 및 sales 열을 사용하여 피벗을 만듭니다. 또한 열린 기회만 가져오려면 'close' salesstage를 제외하도록 stagename을 필터링합니다.

public IBindingList ProductOppportunity()
    {
      var fp = this.CreateFlexPivotEngine(this.QueryName, new string[] { "stagename" }, new string[] { "productname" }, new string[] { "Sales" });
      var fld = fp.ColumnFields[0].Filter;
      fld.Condition1.Operator = ConditionOperator.NotEquals;
      fld.Condition1.Parameter = "close";
      return fp.PivotDefaultView;
    }


다음 결과를 얻게 됩니다.

image2


각 영업 담당자 버킷의 기회 값

각 salesrep의 기회 값을 확인하려면 slaresrep, stagename, sales 필드에서 피벗합니다.

public IBindingList OpportunityByRep()
    {
      var fp = this.CreateFlexPivotEngine(this.QueryName, new string[] { "salesrep" }, new string[] { "stagename" }, new string[] { "Sales" });
      return fp.PivotDefaultView;
    }


모든 단계에서 각 영업 담당자의 매출을 나열하는 다음 결과가 표시됩니다.

image3


각 회계 분기의 기회

C1PivotEngine에서는 한 범위의 데이터를 그룹화하여 의미 있는 정보를 제공할 수 있습니다. C1PivotEngine은 문자열, 숫자, 날짜에 대한 범위 그룹을 만듭니다. 이 사례에서는 분기별 기회 데이터를 가져오기 위해 createdon 필드에 범위 그룹화를 적용합니다. 한 필드에는 날짜를 표시하고 다른 필드는 회계 분기를 가져오는 데 사용할 수 있도록 createdon 필드를 rowfields에 두 번 전달합니다. 이렇게 하면 각 단계의 분기별 예상 매출이 제공됩니다.

public IBindingList OpportunityByFiscalQuarter()
    {
      var fp = this.CreateFlexPivotEngine(this.QueryName, new string[] { "stagename" }, new string[] { "createdon", "createdon" }, new string[] { "Sales" });
      var year = fp.RowFields[0];
      year.Range.RangeType = RangeType.FiscalYear;
      year.Range.FiscalYearFirstMonth = 4;
​
      var month = fp.RowFields[1];
      month.Range.RangeType = RangeType.FiscalQuarter;
​
      return fp.PivotDefaultView;
    }


image4


첨부 파일을 통해 이 응용 프로그램의 전체 코드를 다운로드하여 살펴볼 수 있습니다. 샘플을 실행하려면 Dynamics 365 서버를 기준으로 연결 설정을 업데이트해야 합니다.

DataConnector 라이브러리를 사용하여 Dynamics 365 Sales에서 데이터를 쉽게 가져올 수 있는 것을 확인했습니다. 학습 곡선 없이 알려진 ADO.NET 클래스를 사용하는 것과 같습니다. C1DataEngine 라이브러리를 사용하여 이 데이터에 대한 피벗 변환을 수행하는 방법도 확인했습니다. C1DataEngine 라이브러리는 메모리에 있는 수백만 개의 레코드를 1초 이내에 쿼리하고 집계할 수 있으며, 피벗 변환과 결합되어 강력한 데이터 분석 라이브러리를 만듭니다.




지금 바로 ComponentOne을 다운로드하여 직접 테스트해보세요!

c1.png

 
  • 페이스북으로 공유
  • 트위터로  공유
  • 구글플러스로 공유
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

그레이프시티 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그

인기글

더보기
  • 인기 게시물이 없습니다.
그레이프시티 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@grapecity.com | 전화 : 1670-0583 | 경기도 안양시 동안구 시민대로 230, B-703(관양동, 아크로타워) 그레이프시티(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 Copyright ⓒ 2022 GrapeCity inc.