using BBWY.Client.Extensions; using BBWY.Client.Models; using BBWY.Common.Models; using GalaSoft.MvvmLight.Command; using Microsoft.Win32; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace BBWY.Client.ViewModels { public class ProcurementAuditViewModel : BaseVM, IDenpendency { private AuditFile selectAuditFile; private bool isLoading; private bool isAudited; private bool isShowPayBillPanel; private bool isShowPurchaseOrderPanel; private bool isShowShopOrderPanel; private bool onlyException; public IList AuditFileList { get; set; } public IList AuditPayBillList { get; set; } public IList AuditPurchaseOrderList { get; set; } public IList AuditShopOrderList { get; set; } public IList ShowAuditPayBillList { get; set; } public IList ShowAuditPurchaseOrderList { get; set; } public IList ShowAuditShopOrderList { get; set; } public AuditFile SelectAuditFile { get => selectAuditFile; set { if (Set(ref selectAuditFile, value)) OnSelectAuditFileChanged(); } } public bool IsLoading { get => isLoading; set { Set(ref isLoading, value); } } public bool IsAudited { get => isAudited; set { Set(ref isAudited, value); } } public bool IsShowPayBillPanel { get => isShowPayBillPanel; set { if (Set(ref isShowPayBillPanel, value)) { if (value) { IsShowPurchaseOrderPanel = false; IsShowShopOrderPanel = false; } } } } public bool IsShowPurchaseOrderPanel { get => isShowPurchaseOrderPanel; set { if (Set(ref isShowPurchaseOrderPanel, value)) { if (value) { IsShowPayBillPanel = false; IsShowShopOrderPanel = false; } } } } public bool IsShowShopOrderPanel { get => isShowShopOrderPanel; set { if (Set(ref isShowShopOrderPanel, value)) { if (value) { IsShowPayBillPanel = false; IsShowPurchaseOrderPanel = false; } } } } public bool OnlyException { get => onlyException; set { if (Set(ref onlyException, value)) OnOnlyExceptionChanged(); } } public ICommand AuditCommand { get; set; } public ICommand ClearAuditCommand { get; set; } public ICommand ImportAliPayBillCommand { get; set; } public ICommand Import1688PurchaseOrderCommand { get; set; } public ICommand ImportJDShopOrderCommand { get; set; } public ProcurementAuditViewModel() { AuditFileList = new ObservableCollection(); AuditCommand = new RelayCommand(Audit); ClearAuditCommand = new RelayCommand(ClearAudit); ImportAliPayBillCommand = new RelayCommand(ImportAliPayBill); Import1688PurchaseOrderCommand = new RelayCommand(Import1688PurchaseOrder); ImportJDShopOrderCommand = new RelayCommand(ImportJDShopOrder); AuditFileList = new ObservableCollection(); AuditPayBillList = new List(); AuditPurchaseOrderList = new List(); AuditShopOrderList = new List(); ShowAuditPayBillList = new ObservableCollection(); ShowAuditPurchaseOrderList = new ObservableCollection(); ShowAuditShopOrderList = new ObservableCollection(); //AuditFileList.Add(new AuditFile() { FileName = "支付宝账单20220527.csv", AuditFileType = AuditFileType.账单 }); //AuditFileList.Add(new AuditFile() { FileName = "1688采购单20220527.csv", AuditFileType = AuditFileType.采购单 }); //AuditFileList.Add(new AuditFile() { FileName = "支付宝账单20220527.csv", AuditFileType = AuditFileType.销售订单 }); } private void Audit() { if (IsLoading) return; if (AuditPayBillList.Count() == 0 || AuditPurchaseOrderList.Count() == 0 || AuditShopOrderList.Count() == 0) { MessageBox.Show("审核数据不全", "提示"); return; } var waitList = new List() { new ManualResetEvent(false), new ManualResetEvent(false) }; IsLoading = true; Task.Factory.StartNew(() => { AuditByPayBill(waitList[0]); AuditByPurchaseOrder(waitList[1]); }).ContinueWith(t => { WaitHandle.WaitAll(waitList.ToArray(), -1); IsLoading = false; IsAudited = true; App.Current.Dispatcher.BeginInvoke((Action)delegate { SelectAuditFile = AuditFileList.FirstOrDefault(f => f.AuditFileType == AuditFileType.账单); }); }); } private void AuditByPayBill(EventWaitHandle ewh) { try { foreach (var payBill in AuditPayBillList) { #region 匹配采购单 var relationPurchaseOrder = AuditPurchaseOrderList.FirstOrDefault(p => p.PurchaseOrderId == payBill.MerchantOrderNo); if (relationPurchaseOrder == null) { //未通过商户订单号找到采购单,则通过账单金额和日期匹配 relationPurchaseOrder = AuditPurchaseOrderList.FirstOrDefault(p => p.PayAmount == payBill.ExpenditureAmount && p.PayTime != null && payBill.PayTime != null && Math.Abs((payBill.PayTime.Value - p.PayTime.Value).TotalSeconds) <= 60); } if (relationPurchaseOrder == null) { payBill.ErrorMessage = "未匹配采购单"; continue; } payBill.RelationPurchaseOrderId = relationPurchaseOrder.PurchaseOrderId; #endregion #region 匹配销售订单 var relationShopOrder = AuditShopOrderList.FirstOrDefault(o => (!string.IsNullOrEmpty(o.VenderRemark) && o.VenderRemark.Contains(relationPurchaseOrder.PurchaseOrderId)) || (o.Phone == relationPurchaseOrder.Phone && o.ContactName == relationPurchaseOrder.ContactName && o.PayTime != null && relationPurchaseOrder.PayTime != null && (relationPurchaseOrder.PayTime.Value - o.PayTime.Value).TotalDays <= 2)); if (relationShopOrder == null) { payBill.ErrorMessage = "未匹配销售订单"; continue; } payBill.RelationShopOrderId = relationShopOrder.OrderId; #endregion } } catch (Exception ex) { App.Current.Dispatcher.Invoke(() => MessageBox.Show(ex.Message, "账单匹配")); } finally { ewh.Set(); } } private void AuditByPurchaseOrder(EventWaitHandle ewh) { try { foreach (var purchaseOrder in AuditPurchaseOrderList) { #region 匹配账单 var relationPayBill = AuditPayBillList.FirstOrDefault(b => b.MerchantOrderNo == purchaseOrder.PurchaseOrderId); if (relationPayBill == null) { //未通过商户订单号找到采购单,则通过账单金额和日期匹配 relationPayBill = AuditPayBillList.FirstOrDefault(b => purchaseOrder.PayAmount == b.ExpenditureAmount && purchaseOrder.PayTime != null && b.PayTime != null && Math.Abs((b.PayTime.Value - purchaseOrder.PayTime.Value).TotalSeconds) <= 60); } if (relationPayBill == null) { purchaseOrder.ErrorMessage = "未匹配支付账单"; continue; } purchaseOrder.RelationPayBillNo = relationPayBill.PayBillNo; #endregion #region 匹配销售单 var relationShopOrder = AuditShopOrderList.FirstOrDefault(o => (!string.IsNullOrEmpty(o.VenderRemark) && o.VenderRemark.Contains(purchaseOrder.PurchaseOrderId)) || (o.Phone == purchaseOrder.Phone && o.ContactName == purchaseOrder.ContactName && o.PayTime != null && purchaseOrder.PayTime != null && (purchaseOrder.PayTime.Value - o.PayTime.Value).TotalDays <= 2)); if (relationShopOrder == null) { purchaseOrder.ErrorMessage = "未匹配销售订单"; continue; } purchaseOrder.RelationShopOrderId = relationShopOrder.OrderId; #endregion } } catch (Exception ex) { App.Current.Dispatcher.Invoke(() => MessageBox.Show(ex.Message, "采购单匹配")); } finally { ewh.Set(); } } private void ClearAudit() { SelectAuditFile = null; AuditFileList.Clear(); AuditPayBillList.Clear(); AuditPurchaseOrderList.Clear(); AuditShopOrderList.Clear(); ShowAuditPayBillList.Clear(); ShowAuditPurchaseOrderList.Clear(); ShowAuditShopOrderList.Clear(); IsAudited = false; IsShowPayBillPanel = false; IsShowPurchaseOrderPanel = false; IsShowShopOrderPanel = false; OnlyException = false; } private (string ErrorMessage, string FileName, IList Lines) ImportAuditFile(AuditFileType auditFileType) { var ofd = new OpenFileDialog() { Filter = "CSV Files (*.csv)|*.csv" }; if (ofd.ShowDialog() != true) return (string.Empty, string.Empty, null); var fileName = ofd.FileName.Substring(ofd.FileName.LastIndexOf("\\") + 1); var filePath = ofd.FileName; if (AuditFileList.Any(f => f.FileName == fileName)) return ("文件已存在", string.Empty, null); try { var lines = File.ReadAllLines(filePath, Encoding.GetEncoding("GB2312")).ToList(); AuditFileList.Add(new AuditFile() { FileName = fileName, AuditFileType = auditFileType }); return (string.Empty, fileName, lines); } catch (Exception ex) { return (ex.Message, string.Empty, null); } } /// /// 导入支付宝账单 /// private void ImportAliPayBill() { var importResult = ImportAuditFile(AuditFileType.账单); if (!string.IsNullOrEmpty(importResult.ErrorMessage)) { MessageBox.Show(importResult.ErrorMessage, "导入支付宝账单"); return; } if (importResult.Lines == null || importResult.Lines.Count() == 0) return; //忽略前5行 /* #支付宝账务明细查询 #账号:[20883422054731100156] #起始日期:[2022年04月01日 00:00:00] 终止日期:[2022年05月01日 00:00:00] #-----------------------------------------账务明细列表---------------------------------------- 账务流水号 业务流水号 商户订单号 商品名称 发生时间 对方账号 收入金额(+元) 支出金额(-元) 账户余额(元) 交易渠道 业务类型 备注 */ for (var i = 0; i < 5; i++) importResult.Lines.RemoveAt(0); //忽略后4行 /* #-----------------------------------------账务明细列表结束------------------------------------ #支出合计:681笔,共-39623.27元 #收入合计:85笔,共43889.26元 #导出时间:[2022年05月01日 10:13:45] */ for (var i = 0; i < 4; i++) { importResult.Lines.RemoveAt(importResult.Lines.Count() - 1); } var payBillNo = ""; try { foreach (var line in importResult.Lines) { var array = line.CSVstrToArry(); var expenditureAmount = decimal.Parse(array[7].FormatString()); if (expenditureAmount == 0) //支出为0的账单不参与审计 continue; payBillNo = array[0].FormatString(); if (AuditPayBillList.Any(p => p.PayBillNo == payBillNo)) continue; var payBill = new AuditPayBill() { BelongFileName = importResult.FileName, PayBillNo = payBillNo, PayBillType = PayBillType.AliPay, SourceMerchantOrderNo = array[2].FormatString(), ProductName = array[3].FormatString(), PayTime = DateTime.Parse(array[4].FormatString()), OppositeAccount = array[5].FormatString(), ExpenditureAmount = Math.Abs(expenditureAmount) }; payBill.MerchantOrderNo = payBill.SourceMerchantOrderNo; if (payBill.SourceMerchantOrderNo.StartsWith("T50060NP")) payBill.MerchantOrderNo = payBill.SourceMerchantOrderNo.Substring(8); AuditPayBillList.Add(payBill); } } catch (Exception ex) { MessageBox.Show($"问题账单号{payBillNo} {ex.Message}", "导入支付宝账单"); } } /// /// 导入1688采购单 /// private void Import1688PurchaseOrder() { var importResult = ImportAuditFile(AuditFileType.采购单); if (!string.IsNullOrEmpty(importResult.ErrorMessage)) { MessageBox.Show(importResult.ErrorMessage, "导入1688采购单"); return; } if (importResult.Lines == null || importResult.Lines.Count() == 0) return; //去掉列名 importResult.Lines.RemoveAt(0); var purchaseOrderId = ""; try { foreach (var line in importResult.Lines) { var array = line.CSVstrToArry(); purchaseOrderId = array[0].FormatString(); if (string.IsNullOrEmpty(purchaseOrderId) || AuditPurchaseOrderList.Any(p => p.PurchaseOrderId == purchaseOrderId)) continue; var purchaseOrder = new AuditPurchaseOrder() { PurchaseOrderId = purchaseOrderId, Platform = Platform.阿里巴巴, BelongFileName = importResult.FileName, ProductAmount = decimal.Parse(array[5].FormatString()), Freight = decimal.Parse(array[6].FormatString()), PayAmount = decimal.Parse(array[8].FormatString()), CreateTime = DateTime.Parse(array[10].FormatString()), ContactName = array[13].FormatString(), Address = array[14].FormatString(), Phone = array[17].FormatString(), Quantity = int.Parse(array[20].FormatString()) }; if (!string.IsNullOrEmpty(array[11])) purchaseOrder.PayTime = DateTime.Parse(array[11].FormatString()); AuditPurchaseOrderList.Add(purchaseOrder); } Console.WriteLine(AuditPurchaseOrderList.Count()); } catch (Exception ex) { MessageBox.Show($"问题采购单号{purchaseOrderId} {ex.Message}", "导入1688采购单"); } } /// /// 导入京东销售订单 /// private void ImportJDShopOrder() { var importResult = ImportAuditFile(AuditFileType.销售订单); if (!string.IsNullOrEmpty(importResult.ErrorMessage)) { MessageBox.Show(importResult.ErrorMessage, "导入京东销售订单"); return; } if (importResult.Lines == null || importResult.Lines.Count() == 0) return; //去掉列名 importResult.Lines.RemoveAt(0); var orderId = ""; try { foreach (var line in importResult.Lines) { var array = line.CSVstrToArry(); orderId = array[0].FormatString(); if (string.IsNullOrEmpty(orderId) || AuditShopOrderList.Any(p => p.OrderId == orderId)) continue; var order = new AuditShopOrder() { OrderId = orderId, Platform = Platform.京东, BelongFileName = importResult.FileName, Quantity = int.Parse(array[3].FormatString()), CreateTime = DateTime.Parse(array[5].FormatString()), PayAmount = decimal.Parse(array[10].FormatString()), ContactName = array[14].FormatString(), Address = array[15].FormatString(), Phone = array[16].FormatString(), ProductName = array[2].FormatString(), VenderRemark = array[27].FormatString() }; AuditShopOrderList.Add(order); if (!string.IsNullOrEmpty(array[30])) order.PayTime = DateTime.Parse(array[30].FormatString()); } } catch (Exception ex) { MessageBox.Show($"问题销售订单号{orderId} {ex.Message}", "导入京东销售订单"); } } /// /// 采购审计文件对象改变事件 /// private void OnSelectAuditFileChanged() { if (SelectAuditFile == null) return; if (SelectAuditFile.AuditFileType == AuditFileType.账单) { IsShowPayBillPanel = true; ShowAuditPayBillList.Clear(); var where = AuditPayBillList.Where(b => b.BelongFileName == SelectAuditFile.FileName); if (OnlyException) where = where.Where(b => !string.IsNullOrEmpty(b.ErrorMessage)); var list = where.ToList(); foreach (var b in list) ShowAuditPayBillList.Add(b); } else if (SelectAuditFile.AuditFileType == AuditFileType.采购单) { IsShowPurchaseOrderPanel = true; ShowAuditPurchaseOrderList.Clear(); var where = AuditPurchaseOrderList.Where(p => p.BelongFileName == SelectAuditFile.FileName); if (OnlyException) where = where.Where(p => !string.IsNullOrEmpty(p.ErrorMessage)); var list = where.ToList(); foreach (var p in list) ShowAuditPurchaseOrderList.Add(p); } else if (SelectAuditFile.AuditFileType == AuditFileType.销售订单) { } } private void OnOnlyExceptionChanged() { if (SelectAuditFile == null || AuditFileList.Count() == 0) return; SelectAuditFile = null; SelectAuditFile = AuditFileList.FirstOrDefault(f => f.AuditFileType == AuditFileType.账单); } } }