PageRenderTime 59ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/Apttus.SNowPS/Apttus.SNowPS.Repository/Products/ProdQuoteRepository.cs

https://bitbucket.org/apttus_bmodi/renewals_1.4_new_5feb2018
C# | 1411 lines | 971 code | 178 blank | 262 comment | 259 complexity | a2d4d3ab98388a4c4e3c9f6bcd0a1e53 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /****************************************************************************************
  2. @Name: QuoteRepository.cs
  3. @Author: Asha Tank
  4. @CreateDate: 11 Oct 2017
  5. @Description: Quote header related process
  6. @UsedBy: This will be used by ProdQuoteRepository controller
  7. @ModifiedBy:
  8. @ModifiedDate:
  9. @ChangeDescription:
  10. *****************************************************************************************/
  11. using Apttus.DataAccess.Common.Enums;
  12. using Apttus.DataAccess.Common.Model;
  13. using Apttus.SNowPS.Common;
  14. using Apttus.SNowPS.Model;
  15. using Newtonsoft.Json;
  16. using Newtonsoft.Json.Linq;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using System.Net.Http;
  21. using System.Xml.Linq;
  22. using System.IO;
  23. using System.Reflection;
  24. namespace Apttus.SNowPS.Respository
  25. {
  26. public class ProdQuoteRepository
  27. {
  28. /// <summary>
  29. /// Calculate financial fields of quote header for paased quote id
  30. /// </summary>
  31. /// <param name="QuoteId"></param>
  32. /// <param name="accessToken"></param>
  33. /// <returns></returns>
  34. public HttpResponseMessage GetQuoteDetail(string QuoteId, string accessToken)
  35. {
  36. var errors = new List<Model.ErrorInfo>();
  37. try
  38. {
  39. //Build AQL Query to fetch Quote,Quote Line Items & Product details
  40. var query = new Query(Constants.OBJ_QUOTE);
  41. query.AddColumns(Constants.OBJ_FIELDQUOTELINEITEM.Split(Constants.CHAR_COMMA));
  42. Expression exp = new Expression(ExpressionOperator.AND);
  43. exp.AddCondition(new Condition(Constants.FIELD_ID, FilterOperator.Equal, QuoteId));
  44. query.SetCriteria(exp);
  45. Join quoteLineItem = new Join(Constants.OBJ_QUOTE, Constants.OBJ_CPQ_QUOTELINEITEM, Constants.FIELD_ID, Constants.FIELD_QUOTEID, JoinType.LEFT);
  46. quoteLineItem.EntityAlias = Constants.OBJ_CPQ_QUOTELINEITEM;
  47. query.AddJoin(quoteLineItem);
  48. Join lineItem = new Join(Constants.OBJ_CPQ_QUOTELINEITEM, Constants.OBJ_LINEITEM, Constants.FIELD_DERIVEDFROMId, Constants.FIELD_ID, JoinType.LEFT);
  49. lineItem.EntityAlias = Constants.OBJ_LINEITEM;
  50. query.AddJoin(lineItem);
  51. Join product = new Join(Constants.OBJ_CPQ_QUOTELINEITEM, Constants.OBJ_PRODUCT, Constants.FIELD_PRODUCTID, Constants.FIELD_ID, JoinType.LEFT);
  52. product.EntityAlias = Constants.OBJ_PRODUCT;
  53. query.AddJoin(product);
  54. var jsonQuery = query.Serialize();
  55. //
  56. var reqConfig = new RequestConfigModel();
  57. reqConfig.accessToken = accessToken;
  58. reqConfig.searchType = SearchType.AQL;
  59. reqConfig.objectName = Constants.OBJ_QUOTE;
  60. var response = Utilities.Search(jsonQuery, reqConfig);
  61. ResultQuoteHeaderModel resultQuoteHeaderModel = new ResultQuoteHeaderModel();
  62. if (response != null && response.IsSuccessStatusCode)
  63. {
  64. var responseString = JObject.Parse(response.Content.ReadAsStringAsync().Result).SelectToken(Constants.NODE_SERIALIZEDRESULTENTITIES).ToString();
  65. List<QuoteQuoteLineDetails> QuoteLineList = new List<QuoteQuoteLineDetails>();
  66. QuoteLineList = JsonConvert.DeserializeObject<List<QuoteQuoteLineDetails>>(responseString);
  67. if (QuoteLineList != null && QuoteLineList.Count > 0)
  68. {
  69. DailyExcnageRate objDailyExcnageRate = new DailyExcnageRate();
  70. objDailyExcnageRate = GetExchangeRateDetails(QuoteLineList.FirstOrDefault().cpq_lineitem.CurrencyId, accessToken);
  71. decimal EstimatedTotal = 0;
  72. decimal ProfesionalServiceTotal = 0;
  73. //Calculate quote fields
  74. for (int i = 0; i < QuoteLineList.Count; i++)
  75. {
  76. switch (QuoteLineList[i].crm_Product.ContributesTo.Value)
  77. {
  78. case Constants.TOTALPSREVENUE:
  79. resultQuoteHeaderModel.ext_EducationalServicesandKnowledgeandOther = resultQuoteHeaderModel.ext_EducationalServicesandKnowledgeandOther + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  80. resultQuoteHeaderModel.ext_TotalServicesRevenue = resultQuoteHeaderModel.ext_TotalServicesRevenue + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  81. resultQuoteHeaderModel.ext_TotalPSRevenue = resultQuoteHeaderModel.ext_TotalPSRevenue + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  82. break;
  83. case Constants.SUBSCRIPTIONANDLICENSEREVENUE:
  84. resultQuoteHeaderModel.ext_TotalLicenseValue = resultQuoteHeaderModel.ext_TotalLicenseValue + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  85. resultQuoteHeaderModel.ext_TotalSubscriptionACV = resultQuoteHeaderModel.ext_TotalSubscriptionACV + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.AnnualContractValue);
  86. break;
  87. case Constants.LICENSEREVENUE:
  88. resultQuoteHeaderModel.ext_TotalLicenseValue = resultQuoteHeaderModel.ext_TotalLicenseValue + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  89. break;
  90. case Constants.TRAININGREVENUE:
  91. resultQuoteHeaderModel.ext_TotalServicesRevenue = resultQuoteHeaderModel.ext_TotalServicesRevenue + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  92. resultQuoteHeaderModel.ext_TotalTrainingRevenue = resultQuoteHeaderModel.ext_TotalTrainingRevenue + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  93. break;
  94. case Constants.OTHERREVENUE:
  95. resultQuoteHeaderModel.ext_TotalOtherRevenue = resultQuoteHeaderModel.ext_TotalOtherRevenue + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  96. break;
  97. }
  98. if (QuoteLineList[i].crm_Product.Family != null && QuoteLineList[i].crm_Product.Family.Value == "Professional Services")
  99. {
  100. ProfesionalServiceTotal = ProfesionalServiceTotal + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  101. }
  102. resultQuoteHeaderModel.ext_TotalAnnualListPrice = resultQuoteHeaderModel.ext_TotalAnnualListPrice + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.AnnualContractValue);
  103. EstimatedTotal = EstimatedTotal + Convert.ToDecimal(QuoteLineList[i].cpq_QuoteLineItem.EstimatedTotal);
  104. }
  105. resultQuoteHeaderModel.ext_PreTaxTotals = Convert.ToDecimal(resultQuoteHeaderModel.ext_TotalLicenseValue + resultQuoteHeaderModel.ext_TotalServicesRevenue + resultQuoteHeaderModel.ext_TotalOtherRevenue);
  106. if (ProfesionalServiceTotal != 0)
  107. {
  108. resultQuoteHeaderModel.ext_EstimatedTravelExpenseFees = (ProfesionalServiceTotal * 10) / 100;
  109. }
  110. resultQuoteHeaderModel.ext_EstimatedTotal = EstimatedTotal + resultQuoteHeaderModel.ext_EstimatedTravelExpenseFees;
  111. resultQuoteHeaderModel.Id = QuoteLineList.FirstOrDefault().Id;
  112. //Calculation of USD fields
  113. resultQuoteHeaderModel.ext_USDTotalAnnualListPrice = Convert.ToDecimal(objDailyExcnageRate.ext_Rate * resultQuoteHeaderModel.ext_TotalAnnualListPrice);
  114. resultQuoteHeaderModel.ext_USDTotalLicenseValue = Convert.ToDecimal(objDailyExcnageRate.ext_Rate * resultQuoteHeaderModel.ext_TotalLicenseValue);
  115. resultQuoteHeaderModel.ext_USDTotalOtherRevenue = Convert.ToDecimal(objDailyExcnageRate.ext_Rate * resultQuoteHeaderModel.ext_TotalOtherRevenue);
  116. resultQuoteHeaderModel.ext_USDTotalPSRevenue = Convert.ToDecimal(objDailyExcnageRate.ext_Rate * resultQuoteHeaderModel.ext_TotalPSRevenue);
  117. resultQuoteHeaderModel.ext_USDTotalServicesRevenue = Convert.ToDecimal(objDailyExcnageRate.ext_Rate * resultQuoteHeaderModel.ext_TotalServicesRevenue);
  118. resultQuoteHeaderModel.ext_USDTotalSubscriptionACV = Convert.ToDecimal(objDailyExcnageRate.ext_Rate * resultQuoteHeaderModel.ext_TotalSubscriptionACV);
  119. resultQuoteHeaderModel.ext_USDTotalTrainingRevenue = Convert.ToDecimal(objDailyExcnageRate.ext_Rate * resultQuoteHeaderModel.ext_TotalTrainingRevenue);
  120. //Calculation of USD fields end
  121. }
  122. //return response
  123. List<ResultQuoteHeaderModel> quoteHeaderList = new List<ResultQuoteHeaderModel>();
  124. quoteHeaderList.Add(resultQuoteHeaderModel);
  125. var responseResult = UpdateQuoteHeader(quoteHeaderList, accessToken);
  126. return responseResult;
  127. }
  128. else
  129. {
  130. HttpResponseMessage jsonResponse = new HttpResponseMessage();
  131. Model.ErrorInfo errorInfo = new Model.ErrorInfo();
  132. errorInfo.Message = "Error";
  133. var dict = new Dictionary<string, object>
  134. {
  135. {"Message", "Fail to update records"}
  136. };
  137. errorInfo.Record = dict;
  138. errors.Add(errorInfo);
  139. Utilities.CreateResponse(jsonResponse, errors);
  140. return jsonResponse;
  141. }
  142. }
  143. catch (Exception ex)
  144. {
  145. var resp = new HttpResponseMessage
  146. {
  147. Content = new StringContent("Message :" + ex.Message + " " + "StackStrace :" + ex.StackTrace, System.Text.Encoding.UTF8, "application/json"),
  148. StatusCode = System.Net.HttpStatusCode.BadRequest
  149. };
  150. return resp;
  151. }
  152. }
  153. /// <summary>
  154. /// Get Currency exchange rate based on currency code
  155. /// </summary>
  156. /// <param name="currencyCode"></param>
  157. /// <returns></returns>
  158. public DailyExcnageRate GetExchangeRateDetails(string currencyId, string accessToken)
  159. {
  160. //currencyCode = "USD";
  161. DailyExcnageRate ExchangeRates = new DailyExcnageRate();
  162. accessToken = accessToken != null ? accessToken : Utilities.GetAuthToken();
  163. var reqExchangeRateLineItem = Utilities.GetRequestConfiguration(Constants.OBJ_DAILYEXCHANGERATE, Constants.FIELD_CURRENCYCODE, Constants.FIELD_CURRENCYCODE);
  164. var dictContent = new List<Dictionary<string, object>> { new Dictionary<string, object>() { { "ext_CurrencyCode", currencyId } } };
  165. var resExchangeRate = Utilities.Search(dictContent, reqExchangeRateLineItem);
  166. if (resExchangeRate != null && resExchangeRate.IsSuccessStatusCode)
  167. {
  168. var responseString = JObject.Parse(resExchangeRate.Content.ReadAsStringAsync().Result).SelectToken("SerializedResultEntities").ToString();
  169. List<DailyExcnageRate> ListExchgRates = JsonConvert.DeserializeObject<List<DailyExcnageRate>>(responseString);
  170. // Getting last Created/Modified currency rate
  171. ExchangeRates = ListExchgRates.OrderByDescending(x => x.ModifiedOn).FirstOrDefault();
  172. }
  173. return ExchangeRates;
  174. }
  175. /// <summary>
  176. /// Update Quote Line Items
  177. /// </summary>
  178. /// <param name="lineItems"></param>
  179. /// <param name="accessToken"></param>
  180. /// <returns></returns>
  181. public HttpResponseMessage UpdateQuoteHeader(List<ResultQuoteHeaderModel> quoteHeaderList, string accessToken)
  182. {
  183. var reqConfig = new RequestConfigModel();
  184. reqConfig.accessToken = accessToken;
  185. reqConfig.objectName = Constants.OBJ_QUOTE;
  186. var lstQuoteToUpdate = new List<dynamic>();
  187. foreach (var lstQuoteItems in quoteHeaderList)
  188. {
  189. lstQuoteToUpdate.Add(new
  190. {
  191. Id = lstQuoteItems.Id,
  192. ext_EducationalServicesandKnowledgeandOther = lstQuoteItems.ext_EducationalServicesandKnowledgeandOther,
  193. ext_TotalServicesRevenue = lstQuoteItems.ext_TotalServicesRevenue,
  194. ext_TotalPSRevenue = lstQuoteItems.ext_TotalPSRevenue,
  195. ext_TotalSubscriptionACV = lstQuoteItems.ext_TotalSubscriptionACV,
  196. ext_TotalLicenseValue = lstQuoteItems.ext_TotalLicenseValue,
  197. ext_TotalTrainingRevenue = lstQuoteItems.ext_TotalTrainingRevenue,
  198. ext_TotalOtherRevenue = lstQuoteItems.ext_TotalOtherRevenue,
  199. ext_TotalAnnualListPrice = lstQuoteItems.ext_TotalAnnualListPrice,
  200. ext_PreTaxTotals = lstQuoteItems.ext_PreTaxTotals,
  201. ext_EstimatedTravelExpenseFees = lstQuoteItems.ext_EstimatedTravelExpenseFees,
  202. ext_EstimatedTotal = lstQuoteItems.ext_EstimatedTotal,
  203. ext_USDTotalAnnualListPrice = lstQuoteItems.ext_USDTotalAnnualListPrice,
  204. ext_USDTotalLicenseValue = lstQuoteItems.ext_USDTotalLicenseValue,
  205. ext_USDTotalOtherRevenue = lstQuoteItems.ext_USDTotalOtherRevenue,
  206. ext_USDTotalPSRevenue = lstQuoteItems.ext_USDTotalPSRevenue,
  207. ext_USDTotalServicesRevenue = lstQuoteItems.ext_USDTotalServicesRevenue,
  208. ext_USDTotalSubscriptionACV = lstQuoteItems.ext_USDTotalSubscriptionACV,
  209. ext_USDTotalTrainingRevenue = lstQuoteItems.ext_USDTotalTrainingRevenue
  210. });
  211. }
  212. var responseString = Utilities.Update(lstQuoteToUpdate, reqConfig);
  213. return responseString;
  214. }
  215. #region Commented Code
  216. ///// <summary>
  217. ///// Calculate financial fields of Quote line items for given QuoteId
  218. ///// </summary>
  219. ///// <param name="QuoteId"></param>
  220. ///// <param name="accessToken"></param>
  221. ///// <returns></returns>
  222. //public HttpResponseMessage UpdateQuoteLineItemFields(string QuoteId, string accessToken)
  223. //{
  224. // var errors = new List<Model.ErrorInfo>();
  225. // try
  226. // {
  227. // //Build AQL Query to fetch Quote,Quote Line Items & Product details
  228. // var query = new Query(Constants.OBJ_QUOTE);
  229. // query.AddColumns(Constants.OBJ_FIELDQUOTELINEITEMFINANCIAL.Split(Constants.CHAR_COMMA));
  230. // Expression exp = new Expression(ExpressionOperator.AND);
  231. // exp.AddCondition(new Condition(Constants.FIELD_ID, FilterOperator.Equal, QuoteId));
  232. // query.SetCriteria(exp);
  233. // Join quoteLineItem = new Join(Constants.OBJ_QUOTE, Constants.OBJ_CPQ_QUOTELINEITEM, Constants.FIELD_ID, Constants.FIELD_QUOTEID, JoinType.LEFT);
  234. // quoteLineItem.EntityAlias = Constants.OBJ_CPQ_QUOTELINEITEM;
  235. // query.AddJoin(quoteLineItem);
  236. // Join lineItem = new Join(Constants.OBJ_CPQ_QUOTELINEITEM, Constants.OBJ_LINEITEM, Constants.FIELD_DERIVEDFROMId, Constants.FIELD_ID, JoinType.LEFT);
  237. // lineItem.EntityAlias = Constants.OBJ_LINEITEM;
  238. // query.AddJoin(lineItem);
  239. // Join product = new Join(Constants.OBJ_CPQ_QUOTELINEITEM, Constants.OBJ_PRODUCT, Constants.FIELD_PRODUCTID, Constants.FIELD_ID, JoinType.LEFT);
  240. // product.EntityAlias = Constants.OBJ_PRODUCT;
  241. // query.AddJoin(product);
  242. // var jsonQuery = query.Serialize();
  243. // var reqConfig = new RequestConfigModel();
  244. // reqConfig.accessToken = accessToken;
  245. // reqConfig.searchType = SearchType.AQL;
  246. // reqConfig.objectName = Constants.OBJ_QUOTE;
  247. // var response = Utilities.Search(jsonQuery, reqConfig);
  248. // ResultUSDQuoteHeaderLineItemFields resultQuoteHeaderAndLIneItems = new ResultUSDQuoteHeaderLineItemFields();
  249. // ResultQuoteHeaderModel resultQuoteHeaderModel = new ResultQuoteHeaderModel();
  250. // List<ResultQuoteLineItem> lstResultQuoteLineItem = new List<ResultQuoteLineItem>();
  251. // if (response != null && response.IsSuccessStatusCode)
  252. // {
  253. // var responseString = JObject.Parse(response.Content.ReadAsStringAsync().Result).SelectToken(Constants.NODE_SERIALIZEDRESULTENTITIES).ToString();
  254. // List<QuoteQuoteLineDetails> QuoteLineList = new List<QuoteQuoteLineDetails>();
  255. // QuoteLineList = JsonConvert.DeserializeObject<List<QuoteQuoteLineDetails>>(responseString);
  256. // if (QuoteLineList != null && QuoteLineList.Count > 0)
  257. // {
  258. // LineItemRepository lineItemRepo = new LineItemRepository();
  259. // //Calculate quote line item USD fields
  260. // for (int i = 0; i < QuoteLineList.Count; i++)
  261. // {
  262. // ResultQuoteLineItem objResultQuoteLineItem = new ResultQuoteLineItem();
  263. // objResultQuoteLineItem.Id = QuoteLineList[i].cpq_QuoteLineItem.Id;
  264. // //get daily currenct exchange rates based on currency code
  265. // DailyExcnageRate objDailyExcnageRate = lineItemRepo.GetExchangeRateDetails(QuoteLineList[i].cpq_lineitem.CurrencyId, accessToken);
  266. // //USD fields
  267. // if (objDailyExcnageRate != null)
  268. // {
  269. // objResultQuoteLineItem.ext_USDAdjustment = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.Ext_AdjustmentAmount;
  270. // objResultQuoteLineItem.ext_USDBasePrice = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.BasePrice;
  271. // objResultQuoteLineItem.ext_USDTotalValue = objDailyExcnageRate.ext_Rate * (QuoteLineList[i].cpq_QuoteLineItem.NetPrice);
  272. // objResultQuoteLineItem.ext_USDListPrice = objDailyExcnageRate.ext_Rate * (QuoteLineList[i].cpq_QuoteLineItem.ListPrice);
  273. // objResultQuoteLineItem.ext_USDSalesPrice = objDailyExcnageRate.ext_Rate * (QuoteLineList[i].cpq_QuoteLineItem.NetUnitPrice);
  274. // objResultQuoteLineItem.ext_USDAnnualContractValue = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.AnnualContractValue;
  275. // objResultQuoteLineItem.ext_USDAnnualListPrice = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.AnnualListPrice;
  276. // }
  277. // lstResultQuoteLineItem.Add(objResultQuoteLineItem);
  278. // }
  279. // }
  280. // resultQuoteHeaderAndLIneItems.ListQuoteLineItemFinFields = lstResultQuoteLineItem;
  281. // var responseResult = UpdateQuoteLineItems(lstResultQuoteLineItem, accessToken);
  282. // return responseResult;
  283. // }
  284. // else
  285. // {
  286. // HttpResponseMessage jsonResponse = new HttpResponseMessage();
  287. // Model.ErrorInfo errorInfo = new Model.ErrorInfo();
  288. // errorInfo.Message = "Error";
  289. // var dict = new Dictionary<string, object>
  290. // {
  291. // {"Message", "Fail to update records"}
  292. // };
  293. // errorInfo.Record = dict;
  294. // errors.Add(errorInfo);
  295. // Utilities.CreateResponse(jsonResponse, errors);
  296. // return jsonResponse;
  297. // }
  298. // //return response
  299. // }
  300. // catch (Exception ex)
  301. // {
  302. // var resp = new HttpResponseMessage
  303. // {
  304. // Content = new StringContent("Message :" + ex.Message + " " + "StackStrace :" + ex.StackTrace, System.Text.Encoding.UTF8, "application/json"),
  305. // StatusCode = System.Net.HttpStatusCode.BadRequest
  306. // };
  307. // return resp;
  308. // }
  309. //}
  310. #endregion
  311. /// <summary>
  312. /// Calculate financial fields of Quote line items for given QuoteId
  313. /// </summary>
  314. /// <param name="QuoteId"></param>
  315. /// <param name="accessToken"></param>
  316. /// <returns></returns>
  317. public HttpResponseMessage UpdateQuoteLineItemFields(string QuoteId, string accessToken)
  318. {
  319. var errors = new List<Model.ErrorInfo>();
  320. try
  321. {
  322. //Build AQL Query to fetch Quote,Quote Line Items & Product details
  323. var query = new Query(Constants.OBJ_QUOTE);
  324. query.AddColumns(Constants.OBJ_FIELDQUOTELINEITEMFINANCIAL.Split(Constants.CHAR_COMMA));
  325. Expression exp = new Expression(ExpressionOperator.AND);
  326. exp.AddCondition(new Condition(Constants.FIELD_ID, FilterOperator.Equal, QuoteId));
  327. query.SetCriteria(exp);
  328. Join quoteLineItem = new Join(Constants.OBJ_QUOTE, Constants.OBJ_CPQ_QUOTELINEITEM, Constants.FIELD_ID, Constants.FIELD_QUOTEID, JoinType.LEFT);
  329. quoteLineItem.EntityAlias = Constants.OBJ_CPQ_QUOTELINEITEM;
  330. query.AddJoin(quoteLineItem);
  331. Join lineItem = new Join(Constants.OBJ_CPQ_QUOTELINEITEM, Constants.OBJ_LINEITEM, Constants.FIELD_DERIVEDFROMId, Constants.FIELD_ID, JoinType.LEFT);
  332. lineItem.EntityAlias = Constants.OBJ_LINEITEM;
  333. query.AddJoin(lineItem);
  334. Join product = new Join(Constants.OBJ_CPQ_QUOTELINEITEM, Constants.OBJ_PRODUCT, Constants.FIELD_PRODUCTID, Constants.FIELD_ID, JoinType.LEFT);
  335. product.EntityAlias = Constants.OBJ_PRODUCT;
  336. query.AddJoin(product);
  337. var jsonQuery = query.Serialize();
  338. var reqConfig = new RequestConfigModel();
  339. reqConfig.accessToken = accessToken;
  340. reqConfig.searchType = SearchType.AQL;
  341. reqConfig.objectName = Constants.OBJ_QUOTE;
  342. var response = Utilities.Search(jsonQuery, reqConfig);
  343. ResultUSDQuoteHeaderLineItemFields resultQuoteHeaderAndLIneItems = new ResultUSDQuoteHeaderLineItemFields();
  344. ResultQuoteHeaderModel resultQuoteHeaderModel = new ResultQuoteHeaderModel();
  345. List<ResultQuoteLineItem> lstResultQuoteLineItem = new List<ResultQuoteLineItem>();
  346. if (response != null && response.IsSuccessStatusCode)
  347. {
  348. var responseString = JObject.Parse(response.Content.ReadAsStringAsync().Result).SelectToken(Constants.NODE_SERIALIZEDRESULTENTITIES).ToString();
  349. List<QuoteQuoteLineDetails> QuoteLineList = new List<QuoteQuoteLineDetails>();
  350. QuoteLineList = JsonConvert.DeserializeObject<List<QuoteQuoteLineDetails>>(responseString);
  351. if (QuoteLineList != null && QuoteLineList.Count > 0)
  352. {
  353. LineItemRepository lineItemRepo = new LineItemRepository();
  354. //Calculate quote line item USD fields
  355. for (int i = 0; i < QuoteLineList.Count; i++)
  356. {
  357. ResultQuoteLineItem objResultQuoteLineItem = new ResultQuoteLineItem();
  358. objResultQuoteLineItem.Id = QuoteLineList[i].cpq_QuoteLineItem.Id;
  359. objResultQuoteLineItem.ext_ListPriceWithAdjustments = QuoteLineList[i].cpq_QuoteLineItem.BasePrice.ConvertToDecimal();
  360. if (QuoteLineList[i].cpq_QuoteLineItem.ListPrice != 0)
  361. {
  362. objResultQuoteLineItem.ext_AdjustmentAmount = (QuoteLineList[i].cpq_QuoteLineItem.ListPrice.ConvertToDecimal() * QuoteLineList[i].cpq_QuoteLineItem.Quantity2.ConvertToDecimal() * QuoteLineList[i].cpq_QuoteLineItem.Term.ConvertToDecimal()) - QuoteLineList[i].cpq_QuoteLineItem.NetPrice.ConvertToDecimal();
  363. objResultQuoteLineItem.ext_AdjustmentDiscountPercent = objResultQuoteLineItem.ext_AdjustmentAmount * 100 / (QuoteLineList[i].cpq_QuoteLineItem.ListPrice.ConvertToDecimal() * QuoteLineList[i].cpq_QuoteLineItem.Quantity2.ConvertToDecimal() * QuoteLineList[i].cpq_QuoteLineItem.Term.ConvertToDecimal());
  364. }
  365. if (QuoteLineList[i].crm_Product.Family != null && QuoteLineList[i].crm_Product.Family.Value.ConvertToStringNull() != null && QuoteLineList[i].cpq_QuoteLineItem.ProductId.Ext_Family.Value.ToString() != Constants.STR_SUBSCRIPTION)
  366. {
  367. objResultQuoteLineItem.ext_AnnualContractValue = 0;
  368. objResultQuoteLineItem.ext_AnnualListPrice = 0;
  369. }
  370. else
  371. {
  372. if (QuoteLineList[i].cpq_QuoteLineItem.SellingFrequency != null && QuoteLineList[i].cpq_QuoteLineItem.SellingFrequency.ConvertToStringNull() != null && QuoteLineList[i].cpq_QuoteLineItem.SellingFrequency.Value.ToString() == Constants.STR_YEARLY)
  373. {
  374. objResultQuoteLineItem.ext_AnnualContractValue = QuoteLineList[i].cpq_QuoteLineItem.NetUnitPrice.ConvertToDecimal() * QuoteLineList[i].cpq_QuoteLineItem.Quantity2;
  375. objResultQuoteLineItem.ext_AnnualListPrice = QuoteLineList[i].cpq_QuoteLineItem.ListPrice.ConvertToDecimal() * QuoteLineList[i].cpq_QuoteLineItem.Quantity2;
  376. }
  377. else
  378. {
  379. objResultQuoteLineItem.ext_AnnualContractValue = QuoteLineList[i].cpq_QuoteLineItem.NetUnitPrice.ConvertToDecimal() * 12 * QuoteLineList[i].cpq_QuoteLineItem.Quantity2;
  380. objResultQuoteLineItem.ext_AnnualListPrice = QuoteLineList[i].cpq_QuoteLineItem.ListPrice.ConvertToDecimal() * 12 * QuoteLineList[i].cpq_QuoteLineItem.Quantity2;
  381. }
  382. }
  383. objResultQuoteLineItem.ext_EstimatedTax = QuoteLineList[i].cpq_QuoteLineItem.ext_EstimatedTax.ConvertToDecimal();
  384. //Estimated Total: Total Value + EstimatedTax
  385. objResultQuoteLineItem.ext_EstimatedTotal = QuoteLineList[i].cpq_QuoteLineItem.NetPrice.ConvertToDecimal() + objResultQuoteLineItem.ext_EstimatedTax.ConvertToDecimal();
  386. //Sales Price
  387. objResultQuoteLineItem.ext_SalesPrice = QuoteLineList[i].cpq_QuoteLineItem.NetUnitPrice.ConvertToDecimal();
  388. //get daily currenct exchange rates based on currency code
  389. DailyExcnageRate objDailyExcnageRate = lineItemRepo.GetExchangeRateDetails(QuoteLineList[i].cpq_lineitem.CurrencyId, accessToken);
  390. //USD fields
  391. if (objDailyExcnageRate != null)
  392. {
  393. objResultQuoteLineItem.ext_USDAdjustment = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.Ext_AdjustmentAmount.ConvertToDecimal();
  394. objResultQuoteLineItem.ext_USDBasePrice = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.BasePrice.ConvertToDecimal();
  395. objResultQuoteLineItem.ext_USDTotalValue = objDailyExcnageRate.ext_Rate * (QuoteLineList[i].cpq_QuoteLineItem.NetPrice.ConvertToDecimal());
  396. objResultQuoteLineItem.ext_USDListPrice = objDailyExcnageRate.ext_Rate * (QuoteLineList[i].cpq_QuoteLineItem.ListPrice.ConvertToDecimal());
  397. objResultQuoteLineItem.ext_USDSalesPrice = objDailyExcnageRate.ext_Rate * (QuoteLineList[i].cpq_QuoteLineItem.NetUnitPrice.ConvertToDecimal());
  398. objResultQuoteLineItem.ext_USDAnnualContractValue = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.AnnualContractValue.ConvertToDecimal();
  399. objResultQuoteLineItem.ext_USDAnnualListPrice = objDailyExcnageRate.ext_Rate * QuoteLineList[i].cpq_QuoteLineItem.AnnualListPrice.ConvertToDecimal();
  400. }
  401. lstResultQuoteLineItem.Add(objResultQuoteLineItem);
  402. }
  403. }
  404. resultQuoteHeaderAndLIneItems.ListQuoteLineItemFinFields = lstResultQuoteLineItem;
  405. var responseResult = UpdateQuoteLineItems(lstResultQuoteLineItem, accessToken);
  406. return responseResult;
  407. }
  408. else
  409. {
  410. HttpResponseMessage jsonResponse = new HttpResponseMessage();
  411. Model.ErrorInfo errorInfo = new Model.ErrorInfo();
  412. errorInfo.Message = "Error";
  413. var dict = new Dictionary<string, object>
  414. {
  415. {"Message", "Fail to update records"}
  416. };
  417. errorInfo.Record = dict;
  418. errors.Add(errorInfo);
  419. Utilities.CreateResponse(jsonResponse, errors);
  420. return jsonResponse;
  421. }
  422. //return response
  423. }
  424. catch (Exception ex)
  425. {
  426. var resp = new HttpResponseMessage
  427. {
  428. Content = new StringContent("Message :" + ex.Message + " " + "StackStrace :" + ex.StackTrace, System.Text.Encoding.UTF8, "application/json"),
  429. StatusCode = System.Net.HttpStatusCode.BadRequest
  430. };
  431. return resp;
  432. }
  433. }
  434. /// <summary>
  435. /// Update calculated Quote line items details
  436. /// </summary>
  437. /// <param name="lineItems">list of fileds to be update</param>
  438. /// <returns></returns>
  439. public HttpResponseMessage UpdateQuoteLineItems(List<ResultQuoteLineItem> quoteLineItems, string accessToken)
  440. {
  441. var reqConfig = new RequestConfigModel();
  442. reqConfig.accessToken = accessToken;
  443. reqConfig.objectName = Constants.OBJ_CPQ_QUOTELINEITEM;
  444. var lstLineItemsToUpdate = new List<dynamic>();
  445. foreach (var lstLineItems in quoteLineItems)
  446. {
  447. lstLineItemsToUpdate.Add(new
  448. {
  449. Id = lstLineItems.Id,
  450. ext_ListPriceWithAdjustments = lstLineItems.ext_ListPriceWithAdjustments,
  451. ext_AdjustmentAmount = lstLineItems.ext_AdjustmentAmount,
  452. ext_AdjustmentDiscountPercent = lstLineItems.ext_AdjustmentDiscountPercent,
  453. ext_EstimatedTax = lstLineItems.ext_EstimatedTax,
  454. ext_AnnualContractValue = lstLineItems.ext_AnnualContractValue,
  455. ext_AnnualListPrice = lstLineItems.ext_AnnualListPrice,
  456. ext_EstimatedTotal = lstLineItems.ext_EstimatedTotal,
  457. ext_SalesPrice = lstLineItems.ext_SalesPrice,
  458. ext_USDAdjustment = lstLineItems.ext_USDAdjustment,
  459. ext_USDBasePrice = lstLineItems.ext_USDBasePrice,
  460. ext_USDTotalValue = lstLineItems.ext_USDTotalValue,
  461. ext_USDListPrice = lstLineItems.ext_USDListPrice,
  462. ext_USDSalesPrice = lstLineItems.ext_USDSalesPrice,
  463. ext_USDAnnualContractValue = lstLineItems.ext_USDAnnualContractValue,
  464. ext_USDAnnualListPrice = lstLineItems.ext_USDAnnualListPrice,
  465. });
  466. }
  467. var responseString = Utilities.Update(lstLineItemsToUpdate, reqConfig);
  468. return responseString;
  469. }
  470. /// <summary>
  471. /// Default quote details based on rule conditions
  472. /// </summary>
  473. /// <param name="QuoteId"></param>
  474. /// <param name="accessToken"></param>
  475. /// <returns></returns>
  476. public HttpResponseMessage DefaultQuoteDetails(string QuoteId, string accessToken)
  477. {
  478. try
  479. {
  480. //Build AQL Query to fetch Quote's opprtunityID
  481. var updateResult = new HttpResponseMessage();
  482. var query = new Query(Constants.OBJ_QUOTE);
  483. query.AddColumns(Constants.OBJ_QUOTEVALIDATE_DEFAULT_SELECTFIELD.Split(Constants.CHAR_COMMA));
  484. Expression exp = new Expression(ExpressionOperator.AND);
  485. exp.AddCondition(new Condition(Constants.FIELD_ID, FilterOperator.Equal, QuoteId));
  486. Join account = new Join(Constants.OBJ_QUOTE, Constants.OBJ_ACCOUNT, Constants.FIELD_ACCOUNTID, Constants.FIELD_ID, JoinType.LEFT);
  487. account.EntityAlias = Constants.OBJ_ACCOUNT;
  488. query.AddJoin(account);
  489. query.SetCriteria(exp);
  490. var jsonQuery = query.Serialize();
  491. var reqConfig = new RequestConfigModel();
  492. reqConfig.accessToken = accessToken;
  493. reqConfig.searchType = SearchType.AQL;
  494. reqConfig.objectName = Constants.OBJ_QUOTE;
  495. var response = Utilities.Search(jsonQuery, reqConfig);
  496. ValidateDefaultQuoteResult objValidateDefaultQuoteResult = new ValidateDefaultQuoteResult();
  497. List<Dictionary<string, object>> ListQuoteFieldToUpdate = new List<Dictionary<string, object>>();
  498. if (response != null && response.IsSuccessStatusCode)
  499. {
  500. var responseString = JObject.Parse(response.Content.ReadAsStringAsync().Result).SelectToken(Constants.NODE_SERIALIZEDRESULTENTITIES).ToString();
  501. List<QuoteValidate> objQuoteOppoDetails = new List<QuoteValidate>();
  502. objQuoteOppoDetails = JsonConvert.DeserializeObject<List<QuoteValidate>>(responseString);
  503. if (objQuoteOppoDetails != null && objQuoteOppoDetails.Count > 0)
  504. {
  505. #region "Set default data center based on Country"
  506. if (objQuoteOppoDetails.FirstOrDefault().crm_Account != null && objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country != null)
  507. {
  508. #region get country and data center mapping data from xml file
  509. Dictionary<string, string> countryDCDict = new Dictionary<string, string>();
  510. string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"XMLFiles\DataCenterCountryMapping.xml");
  511. XDocument XDoc = XDocument.Load(path);
  512. try
  513. {
  514. countryDCDict = XDoc.Descendants("Country").ToDictionary(d => (string)d.Attribute("Name"), d => (string)d);
  515. if (countryDCDict.ContainsKey(objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country))
  516. {
  517. objValidateDefaultQuoteResult.ext_datacenter = countryDCDict[objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country];
  518. }
  519. else
  520. { //setting default data center to United States
  521. objValidateDefaultQuoteResult.ext_datacenter = countryDCDict[Constants.STR_UNITEDSTATES];
  522. }
  523. }
  524. catch (Exception ex)
  525. {
  526. objValidateDefaultQuoteResult.ErrorMessage = "DataCenterCountryMapping :" + ex.Message;
  527. }
  528. #endregion
  529. }
  530. #endregion
  531. #region "Set Selling entity"
  532. if (objQuoteOppoDetails.FirstOrDefault().crm_Account != null && objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country != null)
  533. {
  534. #region get country and selling entity mapping data from xml file
  535. Dictionary<string, string> countryDCDict = new Dictionary<string, string>();
  536. string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"XMLFiles\CountryandSellingEntityMapping.xml");
  537. XDocument XDoc = XDocument.Load(path);
  538. try
  539. {
  540. countryDCDict = XDoc.Descendants("Country").ToDictionary(d => (string)d.Attribute("Name"), d => (string)d);
  541. if (countryDCDict.ContainsKey(objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country))
  542. {
  543. objValidateDefaultQuoteResult.ext_SellingEntity = countryDCDict[objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country];
  544. }
  545. else
  546. {
  547. objValidateDefaultQuoteResult.ext_SellingEntity = countryDCDict[Constants.STR_NEDERLAND];
  548. }
  549. }
  550. catch (Exception ex)
  551. {
  552. objValidateDefaultQuoteResult.ErrorMessage += " CountryandSellingEntityMapping :" + ex.Message;
  553. }
  554. #endregion
  555. }
  556. #endregion
  557. #region "Set PriceList based on currency and vice versa"
  558. //Build AQL Query to fetch pricelist details
  559. var priceListId = objQuoteOppoDetails.FirstOrDefault().PriceListId != null ? objQuoteOppoDetails.FirstOrDefault().PriceListId.Id : null;
  560. if (!string.IsNullOrEmpty(priceListId))
  561. {
  562. var queryPricelist = new Query(Constants.OBJ_PRICELIST);
  563. queryPricelist.AddColumns(Constants.OBJ_PRICELIST_SELECTFIELD.Split(Constants.CHAR_COMMA));
  564. Expression expPriceList = new Expression(ExpressionOperator.AND);
  565. expPriceList.AddCondition(new Condition(Constants.FIELD_ID, FilterOperator.Equal, priceListId));
  566. queryPricelist.SetCriteria(expPriceList);
  567. jsonQuery = queryPricelist.Serialize();
  568. reqConfig = new RequestConfigModel();
  569. reqConfig.accessToken = accessToken;
  570. reqConfig.searchType = SearchType.AQL;
  571. reqConfig.objectName = Constants.OBJ_PRICELIST;
  572. var responsePricelistDetail = Utilities.Search(jsonQuery, reqConfig);
  573. if (responsePricelistDetail != null && responsePricelistDetail.IsSuccessStatusCode)
  574. {
  575. var responsePriceListString = JObject.Parse(responsePricelistDetail.Content.ReadAsStringAsync().Result).SelectToken(Constants.NODE_SERIALIZEDRESULTENTITIES).ToString();
  576. List<QQuoteLineItem> objPriceListResult = new List<QQuoteLineItem>();
  577. objPriceListResult = JsonConvert.DeserializeObject<List<QQuoteLineItem>>(responsePriceListString);
  578. if (objPriceListResult != null && objPriceListResult.Count > 0)
  579. {
  580. if (!string.IsNullOrEmpty(objPriceListResult.FirstOrDefault().CurrencyId))
  581. {
  582. objValidateDefaultQuoteResult.BaseCurrency = objPriceListResult.FirstOrDefault().CurrencyId;
  583. }
  584. }
  585. }
  586. }
  587. // PricelistId will be null when Quote is created outside Apttus
  588. if (!string.IsNullOrEmpty(objQuoteOppoDetails.FirstOrDefault().ext_BaseCurrency) && string.IsNullOrEmpty(priceListId))
  589. {
  590. if (objQuoteOppoDetails.FirstOrDefault().ext_Type.Value.ToLower() == Constants.SERVICES || objQuoteOppoDetails.FirstOrDefault().ext_Type.Value.ToLower() == Constants.STR_TRAINING.ToLower())
  591. {
  592. #region get Currency and Pricelist mapping data from xml file for Services
  593. Dictionary<string, string> currencyDCDict = new Dictionary<string, string>();
  594. string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"XMLFiles\CurrencyandPriceListMappingServices.xml");
  595. XDocument XDoc = XDocument.Load(path);
  596. try
  597. {
  598. currencyDCDict = XDoc.Descendants("Currency").ToDictionary(d => (string)d.Attribute("Name"), d => (string)d);
  599. if (currencyDCDict.ContainsKey(objQuoteOppoDetails.FirstOrDefault().ext_BaseCurrency))
  600. {
  601. objValidateDefaultQuoteResult.PriceListName = currencyDCDict[objQuoteOppoDetails.FirstOrDefault().ext_BaseCurrency];
  602. if (objQuoteOppoDetails.FirstOrDefault().ext_BaseCurrency == Constants.STR_USD)
  603. {
  604. if (objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country == Constants.STR_AUSTRALIA)
  605. {
  606. objValidateDefaultQuoteResult.PriceListName = "Australian (USD) Services";
  607. }
  608. else if (objQuoteOppoDetails.FirstOrDefault().crm_Account.ext_Country == Constants.STR_JAPAN)
  609. {
  610. objValidateDefaultQuoteResult.PriceListName = "Japan (USD) Subscription";
  611. }
  612. }
  613. }
  614. else
  615. {
  616. objValidateDefaultQuoteResult.PriceListName = currencyDCDict[Constants.STR_USD];
  617. }
  618. }
  619. catch (Exception ex)
  620. {
  621. objValidateDefaultQuoteResult.ErrorMessage += " CurrencyandPriceListMappingServices :" + ex.Message;
  622. }
  623. #endregion
  624. }
  625. else// Remaining types will be for Subscription
  626. {
  627. #region get Currency and Pricelist mapping data from xml file for Subscription
  628. Dictionary<string, string> currencyDCDict = new Dictionary<string, string>();
  629. string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"XMLFiles\CurrencyandPriceListMapping.xml");
  630. XDocument XDoc = XDocument.Load(path);
  631. try
  632. {
  633. currencyDCDict = XDoc.Descendants("Currency").ToDictionary(d => (string)d.Attribute("Name"), d => (string)d);
  634. if (currencyDCDict.ContainsKey(objQuoteOppoDetails.FirstOrDefault().ext_BaseCurrency))
  635. {
  636. objValidateDefaultQuoteResult.PriceListName = currencyDCDict[objQuoteOppoDetails.FirstOrDefault().ext_BaseCurrency];
  637. }
  638. else
  639. {
  640. objValidateDefaultQuoteResult.PriceListName = currencyDCDict[Constants.STR_USD];
  641. }
  642. }
  643. catch (Exception ex)
  644. {
  645. objValidateDefaultQuoteResult.ErrorMessage += " CurrencyandPriceListMapping :" + ex.Message;
  646. }
  647. #endregion
  648. }
  649. }
  650. #endregion
  651. //Update Quote fileds to default values
  652. ListQuoteFieldToUpdate = new List<Dictionary<string, object>>();
  653. Dictionary<string, object> QuoteFieldToUpdate = new Dictionary<string, object>();
  654. QuoteFieldToUpdate.Add("Id", QuoteId);
  655. if (!string.IsNullOrEmpty(objValidateDefaultQuoteResult.ext_datacenter))
  656. {
  657. QuoteFieldToUpdate.Add("ext_datacenter", objValidateDefaultQuoteResult.ext_datacenter);
  658. }
  659. if (!string.IsNullOrEmpty(objValidateDefaultQuoteResult.ext_SellingEntity))
  660. {
  661. //Build AQL Query to fetch Account details
  662. var queryQuote = new Query(Constants.OBJ_ACCOUNT);
  663. queryQuote.AddColumns(Constants.OBJ_ACCOUNT_SELECTFIELD.Split(Constants.CHAR_COMMA));
  664. Expression expQuote = new Expression(ExpressionOperator.AND);
  665. expQuote.AddCondition(new Condition(Constants.FIELD_NAME, FilterOperator.Equal, objValidateDefaultQuoteResult.ext_SellingEntity));
  666. queryQuote.SetCriteria(expQuote);
  667. jsonQuery = queryQuote.Serialize();
  668. reqConfig = new RequestConfigModel();
  669. reqConfig.accessToken = accessToken;
  670. reqConfig.searchType = SearchType.AQL;
  671. reqConfig.objectName = Constants.OBJ_ACCOUNT;
  672. var responseAccountDetail = Utilities.Search(jsonQuery, reqConfig);
  673. if (responseAccountDetail != null && responseAccountDetail.IsSuccessStatusCode)
  674. {
  675. var responseAccountString = JObject.Parse(responseAccountDetail.Content.ReadAsStringAsync().Result).SelectToken(Constants.NODE_SERIALIZEDRESULTENTITIES).ToString();
  676. List<AccountCountry> objAccountResult = new List<AccountCountry>();
  677. objAccountResult = JsonConvert.DeserializeObject<List<AccountCountry>>(responseAccountString);
  678. if (objAccountResult != null && objAccountResult.Count > 0)
  679. {
  680. Dictionary<string, object> dictAccount = new Dictionary<string, object>();
  681. dictAccount.Add("Id", objAccountResult.FirstOrDefault().Id);
  682. dictAccount.Add("Name", objAccountResult.FirstOrDefault().Name);
  683. QuoteFieldToUpdate.Add("ext_SellingEntity", dictAccount);
  684. }
  685. }
  686. }
  687. if (!string.IsNullOrEmpty(objValidateDefaultQuoteResult.PriceListName))
  688. {
  689. //Build AQL Query to fetch Account details
  690. var queryPriceList = new Query(Constants.OBJ_PRICELIST);
  691. queryPriceList.AddColumns(Constants.OBJ_PRICELIST_SELECTFIELD.Split(Constants.CHAR_COMMA));
  692. Expression expPriceLIst = new Expression(ExpressionOperator.AND);
  693. expP

Large files files are truncated, but you can click here to view the full file