ApplyBuyViewModel.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using GalaSoft.MvvmLight;
  9. using GalaSoft.MvvmLight.Command;
  10. using GalaSoft.MvvmLight.Ioc;
  11. using GalaSoft.MvvmLight.Messaging;
  12. using Microsoft.Practices.ServiceLocation;
  13. using Muchinfo.MTPClient.Data.Enums;
  14. using Muchinfo.MTPClient.Data.Model;
  15. using Muchinfo.MTPClient.Data.Model.Sale;
  16. using Muchinfo.MTPClient.Infrastructure.Utilities;
  17. using Muchinfo.MTPClient.IService;
  18. using Muchinfo.MTPClient.Resources;
  19. using Muchinfo.WPF.Controls.Windows;
  20. namespace Muchinfo.MTPClient.Sale.ViewModels
  21. {
  22. public class ApplyBuyViewModel : ViewModelBase
  23. {
  24. private IOrderService _orderService; //单据服务
  25. private ISaleService _saleService;//发售服务
  26. private List<StrategicInvestor> _strategicInvestors = new List<StrategicInvestor>();//战略投资者商品
  27. #region 构造函数
  28. public string TradeCode { get; set; }
  29. public ApplyBuyViewModel(SaleGoods purchaseGood, ObservableCollection<SaleGoods> saleGoods, List<StrategicInvestor> strategicInvestors)
  30. {
  31. _orderService = SimpleIoc.Default.GetInstance<IOrderService>();
  32. _saleService = ServiceLocator.Current.GetInstance<ISaleService>();
  33. TradeCode = UserManager.CurrentTradeAccount.TradeCode;
  34. RaisePropertyChanged(() => TradeCode);
  35. SaleGoods = saleGoods;
  36. if (strategicInvestors != null)
  37. {
  38. _strategicInvestors = strategicInvestors;
  39. }
  40. GoodsCode = purchaseGood.GoodsCode;
  41. }
  42. #endregion
  43. #region 成员变量
  44. //最小申购数量
  45. private int applyMinQty;
  46. //可购买数量(可用保证金/单价)
  47. private Int64 number;
  48. //申购数量上限
  49. private Int64 maxNumber;
  50. //增量手续费和基本手续费之和
  51. private decimal Charge;
  52. private ObservableCollection<SaleGoods> _saleGoods;
  53. /// <summary>
  54. /// 可申购商品
  55. /// </summary>
  56. public ObservableCollection<SaleGoods> SaleGoods
  57. {
  58. get { return _saleGoods; }
  59. set { Set(() => SaleGoods, ref _saleGoods, value); }
  60. }
  61. private string _goodsCode;
  62. /// <summary>
  63. /// 当前选中的商品
  64. /// </summary>
  65. public string GoodsCode
  66. {
  67. get { return _goodsCode; }
  68. set
  69. {
  70. Set(() => GoodsCode, ref _goodsCode, value);
  71. if (SaleGoods != null)
  72. {
  73. var firstOrDefault = SaleGoods.FirstOrDefault(k => k.GoodsCode == _goodsCode);
  74. if (firstOrDefault == null) { return; }
  75. var strategicInvestor = _strategicInvestors.FirstOrDefault(k => k.GoodsCode == _goodsCode);
  76. if (strategicInvestor == null)
  77. {
  78. SalePrice = firstOrDefault.SalePrice;
  79. maxNumber = int.Parse(firstOrDefault.SingerMaxRatio.ToString()) - firstOrDefault.SumQty;
  80. }
  81. else
  82. {
  83. SalePrice = strategicInvestor.SalePrice;
  84. maxNumber = strategicInvestor.PlacingQty - firstOrDefault.SumQty;
  85. }
  86. applyMinQty = firstOrDefault.ApplyMinQty;
  87. //发售手续费
  88. decimal saleCharge = 0;
  89. //增量手续费
  90. decimal ChargeNum = 0;
  91. if (firstOrDefault.ChargeType == ChargeModeType.FixedNumber)
  92. {
  93. saleCharge = firstOrDefault.ChargeNum / firstOrDefault.AgreeUnit;
  94. }
  95. else
  96. {
  97. saleCharge = firstOrDefault.SalePrice * firstOrDefault.ChargeNum;
  98. }
  99. if (!string.IsNullOrEmpty(UserManager.CurrentTradeAccount.ContentRightType))
  100. {
  101. var rulesIds = UserManager.CurrentTradeAccount.ContentRightType.Split(',').ToList();
  102. var index = -1;
  103. for (int i = 0; i < rulesIds.Count(); i++)
  104. {
  105. if (i % 2 == 0 && rulesIds[i].Equals(UserManager.SaleMarkId + string.Empty))
  106. {
  107. index = i;
  108. break;
  109. }
  110. }
  111. if (index + 1 < rulesIds.Count && index != -1)
  112. {
  113. int pRule = -1;
  114. if (int.TryParse(rulesIds[index + 1], out pRule))
  115. {
  116. var rules = _saleService.QueryParameterRule(pRule, firstOrDefault.GoodsId, UserManager.CurrentTradeAccount.LoginCode);
  117. if (rules != null && rules.Any())
  118. {
  119. if (rules[0].MarketMarginType == ChargeModeType.FixedNumber)
  120. {
  121. ChargeNum = rules[0].MarketMargin / firstOrDefault.AgreeUnit;
  122. }
  123. else
  124. {
  125. ChargeNum = firstOrDefault.SalePrice * rules[0].MarketMargin;
  126. }
  127. }
  128. }
  129. }
  130. }
  131. else
  132. {
  133. Remark = "交易参数获取失败。";
  134. OKButtonEnabled = false;
  135. return;
  136. }
  137. Charge = saleCharge + ChargeNum;
  138. if (Charge > 0) { PurchaseNumber = 0; return; }
  139. if (UserManager.CurrentTradeAccount.AccountType == eAccountType.ACCOUNTTYPE_TRADER)
  140. {
  141. number = Convert.ToInt64(Math.Floor(UserManager.CurrentTradeAccount.FundsAccounts[0].AvailMargin / (firstOrDefault.SalePrice - Charge) / firstOrDefault.AgreeUnit).ToString());
  142. }
  143. else
  144. {
  145. number = Convert.ToInt64(Math.Floor(UserManager.CurrentTradeAccount.MemberAccountInfo.NetWorth / (firstOrDefault.SalePrice - Charge) / firstOrDefault.AgreeUnit).ToString());
  146. }
  147. MaxPurchaseNumber = maxNumber < number ? maxNumber : number;
  148. PurchaseNumber = 0;
  149. }
  150. }
  151. }
  152. private decimal _salePrice;
  153. /// <summary>
  154. /// 当前选中商品价格
  155. /// </summary>
  156. public decimal SalePrice
  157. {
  158. get { return _salePrice; }
  159. set { Set(() => SalePrice, ref _salePrice, value); }
  160. }
  161. private long _purchaseNumber;
  162. /// <summary>
  163. /// 申购数量
  164. /// </summary>
  165. public long PurchaseNumber
  166. {
  167. get { return _purchaseNumber; }
  168. set
  169. {
  170. Set(() => PurchaseNumber, ref _purchaseNumber, value);
  171. if (Charge > 0)
  172. {
  173. Remark = "手续费参数设置错误,不能申购。";
  174. OKButtonEnabled = false;
  175. }
  176. else if (number <= 0)
  177. {
  178. Remark = "资金不足。";
  179. OKButtonEnabled = false;
  180. }
  181. else if (maxNumber <= 0)
  182. {
  183. Remark = "已达申购总量限制,不能继续申购。";
  184. OKButtonEnabled = false;
  185. }
  186. else if (_purchaseNumber > MaxPurchaseNumber)
  187. {
  188. Remark = "已超出最大申购数量,不能继续申购。";
  189. OKButtonEnabled = false;
  190. }
  191. else if (_purchaseNumber < applyMinQty)
  192. {
  193. Remark = string.Format(Muchinfo_Resource.ApplyBuy_MinNum, applyMinQty);
  194. OKButtonEnabled = false;
  195. }
  196. else if (_purchaseNumber % applyMinQty != 0)
  197. {
  198. Remark = string.Format(Muchinfo_Resource.ApplyBuy_IntNum, applyMinQty);
  199. OKButtonEnabled = false;
  200. }
  201. else
  202. {
  203. Remark = "";
  204. OKButtonEnabled = true;
  205. }
  206. }
  207. }
  208. private Int64 _maxPurchaseNumber;
  209. /// <summary>
  210. /// 最大申购数量
  211. /// 申购投资者的可申购金额计算出的对应可申购数量和商品管理中设置的每个申购投资者申购数量上限进行比较,取二者的较小值。
  212. /// </summary>
  213. public Int64 MaxPurchaseNumber
  214. {
  215. get { return _maxPurchaseNumber; }
  216. set { Set(() => MaxPurchaseNumber, ref _maxPurchaseNumber, value); }
  217. }
  218. private bool _okButtonEnabled = true;
  219. public bool OKButtonEnabled
  220. {
  221. get { return _okButtonEnabled; }
  222. set { Set(() => OKButtonEnabled, ref _okButtonEnabled, value); }
  223. }
  224. private string _remark;
  225. public string Remark
  226. {
  227. get { return _remark; }
  228. set { Set(() => Remark, ref _remark, value); }
  229. }
  230. private List<Commission> _bidCommissions = SortCommissions(true);
  231. /// <summary>
  232. /// 显示买入档
  233. /// </summary>
  234. public List<Commission> BidCommissions
  235. {
  236. get { return _bidCommissions; }
  237. set { Set(() => BidCommissions, ref _bidCommissions, value); }
  238. }
  239. private List<Commission> _askCommissions = SortCommissions(false);
  240. /// <summary>
  241. /// 显示卖出档
  242. /// </summary>
  243. public List<Commission> AskCommissions
  244. {
  245. get { return _askCommissions; }
  246. set { Set(() => AskCommissions, ref _askCommissions, value); }
  247. }
  248. private string _busyTips;
  249. /// <summary>
  250. /// 服务忙提示
  251. /// </summary>
  252. public string BusyTips
  253. {
  254. get
  255. {
  256. return _busyTips;
  257. }
  258. set
  259. {
  260. Set(() => BusyTips, ref _busyTips, value);
  261. }
  262. }
  263. private bool _isBusy;
  264. /// <summary>
  265. /// 是否忙,显示等待控件
  266. /// </summary>
  267. public bool IsBusy
  268. {
  269. get
  270. {
  271. return _isBusy;
  272. }
  273. set
  274. {
  275. Set(() => IsBusy, ref _isBusy, value);
  276. }
  277. }
  278. #endregion
  279. #region 私有方法
  280. /// <summary>
  281. /// 设置买卖档
  282. /// </summary>
  283. /// <param name="bid">if set to <c>true</c> [bid].</param>
  284. /// <param name="commissions">The commissions.</param>
  285. /// <returns>List{Commission}.</returns>
  286. private static List<Commission> SortCommissions(bool bid)
  287. {
  288. var commissionLsit = new List<Commission>();
  289. for (int i = 1; i < 6; i++)
  290. {
  291. Commission cs = new Commission()
  292. {
  293. Index = i,
  294. Volume = 0
  295. };
  296. commissionLsit.Add(cs);
  297. }
  298. if (!bid)
  299. {
  300. commissionLsit = commissionLsit.OrderByDescending((item) => item.Index).ToList();
  301. }
  302. return commissionLsit;
  303. }
  304. public RelayCommand<Window> CancelCommand
  305. {
  306. get
  307. {
  308. return new RelayCommand<Window>((dialog) =>
  309. {
  310. dialog.DialogResult = false;
  311. });
  312. }
  313. }
  314. public RelayCommand<Window> OKCommand
  315. {
  316. get
  317. {
  318. return new RelayCommand<Window>((dialog) =>
  319. {
  320. OKButtonEnabled = false;
  321. string errorMsg = string.Empty;
  322. bool validateBool = VailedFormData(out errorMsg);
  323. if (validateBool)
  324. {
  325. IsBusy = true;
  326. BusyTips = "正在提交数据,请稍候...";
  327. Task.Factory.StartNew(() =>
  328. {
  329. EntrustOrder order;
  330. try
  331. {
  332. int errorCode = PostOrder(out order);
  333. Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  334. {
  335. if (errorCode == 0)
  336. {
  337. MessageBoxHelper.ShowSuccess(Muchinfo_Resource.Content_ApplyOK, Muchinfo_Resource.Content_ApplyRemarkTitle);
  338. if (dialog.IsLoaded)
  339. {
  340. dialog.DialogResult = true;
  341. }
  342. // LogManager.WriteEntrustLog(order, GoodsCode);
  343. }
  344. else
  345. {
  346. ErrorManager.ShowReturnError(errorCode, Muchinfo_Resource.MessageBox_Error_Title);
  347. OKButtonEnabled = true;
  348. }
  349. Messenger.Default.Send(true, MessengerTokens.RefrashSaleGoodsCommand);
  350. IsBusy = false;
  351. }));
  352. }
  353. catch (Exception ex)
  354. {
  355. Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  356. {
  357. IsBusy = false;
  358. OKButtonEnabled = true;
  359. throw new Exception(ex.Message);
  360. }));
  361. }
  362. });
  363. }
  364. else
  365. {
  366. MessageBoxHelper.ShowInfo(errorMsg, Muchinfo_Resource.MessageBox_Error_Title);
  367. OKButtonEnabled = true;
  368. }
  369. });
  370. }
  371. }
  372. /// <summary>
  373. /// 发送下单消息
  374. /// </summary>
  375. /// <param name="order">The order.</param>
  376. /// <returns>返回下单错误码</returns>
  377. private int PostOrder(out EntrustOrder order)
  378. {
  379. var entrustOrder = new EntrustOrder()
  380. {
  381. TradeCode = UserManager.CurrentTradeAccount.TradeCode,
  382. GoodsCode = GoodsCode,
  383. AccountType = UserManager.CurrentTradeAccount.AccountType,
  384. OrderType = OrderType.OrderTypeSale,
  385. BuyOrSell = Direction.Bid,
  386. EntrustQuantity = PurchaseNumber,
  387. EntrustPrice = SalePrice
  388. };
  389. order = entrustOrder;
  390. return _orderService.EntrustOrder(entrustOrder, UserManager.CurrentTradeAccount.LoginCode);
  391. }
  392. /// <summary>
  393. /// 验证表单数据是否正确
  394. /// </summary>
  395. /// <param name="errorMsg"></param>
  396. /// <returns></returns>
  397. private bool VailedFormData(out string errorMsg)
  398. {
  399. if (string.IsNullOrEmpty(GoodsCode))
  400. {
  401. errorMsg = Muchinfo_Resource.GoodsSelect_Vailed;
  402. return false;
  403. }
  404. errorMsg = string.Empty;
  405. return true;
  406. }
  407. #endregion
  408. }
  409. }