public async Task <IActionResult> PostAssetSellDocument([FromBody] FinanceAssetSellDocumentCreateContext createContext) { if (!ModelState.IsValid) { HIHAPIUtility.HandleModalStateError(ModelState); } if (createContext.HID <= 0) { throw new BadRequestException("Not HID inputted"); } if (createContext.AssetAccountID <= 0) { throw new BadRequestException("Asset Account is invalid"); } if (createContext.TranAmount <= 0) { throw new BadRequestException("Amount is less than zero"); } if (createContext.Items.Count <= 0) { throw new BadRequestException("No items inputted"); } // User String usrName = String.Empty; try { usrName = HIHAPIUtility.GetUserID(this); if (String.IsNullOrEmpty(usrName)) { throw new UnauthorizedAccessException(); } } catch { throw new UnauthorizedAccessException(); } // Check whether User assigned with specified Home ID var hms = _context.HomeMembers.Where(p => p.HomeID == createContext.HID && p.User == usrName).Count(); if (hms <= 0) { throw new UnauthorizedAccessException(); } // Construct the Doc. var vmFIDoc = new FinanceDocument(); vmFIDoc.DocType = FinanceDocumentType.DocType_AssetSoldOut; vmFIDoc.Desp = createContext.Desp; vmFIDoc.TranDate = createContext.TranDate; vmFIDoc.HomeID = createContext.HID; vmFIDoc.TranCurr = createContext.TranCurr; Decimal totalAmt = 0; var maxItemID = 0; foreach (var di in createContext.Items) { if (di.ItemID <= 0 || di.TranAmount == 0 || di.AccountID <= 0 || di.TranType != FinanceTransactionType.TranType_AssetSoldoutIncome || (di.ControlCenterID <= 0 && di.OrderID <= 0)) { throw new BadRequestException("Invalid input data in items!"); } totalAmt += di.TranAmount; vmFIDoc.Items.Add(di); if (maxItemID < di.ItemID) { maxItemID = di.ItemID; } } if (Decimal.Compare(totalAmt, createContext.TranAmount) != 0) { throw new BadRequestException("Amount is not even"); } // Check 1: check account is a valid asset? var query = (from account in this._context.FinanceAccount join assetaccount in this._context.FinanceAccountExtraAS on account.ID equals assetaccount.AccountID where account.ID == createContext.AssetAccountID select new { Status = account.Status, RefSellDoc = assetaccount.RefenceSoldDocumentID }).FirstOrDefault(); if (query.Status != (Byte)FinanceAccountStatus.Normal) { throw new BadRequestException("Account status is not normal"); } if (query.RefSellDoc != null) { throw new BadRequestException("Asset has soldout doc already"); } // Check 2: check the inputted date is valid > must be the later than all existing transactions; var query2 = (from docitem in this._context.FinanceDocumentItem join docheader in this._context.FinanceDocument on docitem.DocID equals docheader.ID where docitem.AccountID == createContext.AssetAccountID orderby docheader.TranDate descending select new { TranDate = docheader.TranDate }).FirstOrDefault(); if (createContext.TranDate < query2.TranDate) { throw new BadRequestException("Tran. data is invalid"); } // Check 3. Fetch current balance var query3 = (from acntbal in this._context.FinanceReporAccountGroupView where acntbal.AccountID == createContext.AssetAccountID select acntbal.Balance).First(); if (query3 <= 0) { throw new BadRequestException("Balance is less than zero"); } var nitem = new FinanceDocumentItem(); nitem.ItemID = ++maxItemID; nitem.AccountID = createContext.AssetAccountID; nitem.TranAmount = createContext.TranAmount; nitem.Desp = vmFIDoc.Desp; nitem.TranType = FinanceTransactionType.TranType_AssetSoldout; if (createContext.ControlCenterID.HasValue) { nitem.ControlCenterID = createContext.ControlCenterID.Value; } if (createContext.OrderID.HasValue) { nitem.OrderID = createContext.OrderID.Value; } nitem.DocumentHeader = vmFIDoc; vmFIDoc.Items.Add(nitem); var ncmprst = Decimal.Compare(query3, createContext.TranAmount); if (ncmprst > 0) { var nitem2 = new FinanceDocumentItem(); nitem2.ItemID = ++maxItemID; nitem2.AccountID = createContext.AssetAccountID; nitem2.TranAmount = Decimal.Subtract(query3, createContext.TranAmount); nitem2.Desp = vmFIDoc.Desp; nitem2.TranType = FinanceTransactionType.TranType_AssetValueDecrease; if (createContext.ControlCenterID.HasValue) { nitem2.ControlCenterID = createContext.ControlCenterID.Value; } if (createContext.OrderID.HasValue) { nitem2.OrderID = createContext.OrderID.Value; } nitem.DocumentHeader = vmFIDoc; vmFIDoc.Items.Add(nitem2); } else if (ncmprst < 0) { var nitem2 = new FinanceDocumentItem(); nitem2.ItemID = ++maxItemID; nitem2.AccountID = createContext.AssetAccountID; nitem2.TranAmount = Decimal.Subtract(createContext.TranAmount, query3); nitem2.Desp = vmFIDoc.Desp; nitem2.TranType = FinanceTransactionType.TranType_AssetValueIncrease; if (createContext.ControlCenterID.HasValue) { nitem2.ControlCenterID = createContext.ControlCenterID.Value; } if (createContext.OrderID.HasValue) { nitem2.OrderID = createContext.OrderID.Value; } nitem.DocumentHeader = vmFIDoc; vmFIDoc.Items.Add(nitem2); } // Database update var errorString = ""; var errorOccur = false; var origdocid = 0; using (var transaction = _context.Database.BeginTransaction()) { try { // 1. Create the document vmFIDoc.CreatedAt = DateTime.Now; vmFIDoc.Createdby = usrName; var docEntity = _context.FinanceDocument.Add(vmFIDoc); await _context.SaveChangesAsync(); origdocid = docEntity.Entity.ID; vmFIDoc = docEntity.Entity; transaction.Commit(); } catch (Exception exp) { errorOccur = true; errorString = exp.Message; transaction.Rollback(); } } if (errorOccur) { throw new BadRequestException(errorString); } return(Created(vmFIDoc)); }
public async Task TestCase1(int hid, string currency, string user, Boolean islegacy) { List <int> documentsCreated = new List <int>(); var context = this.fixture.GetCurrentDataContext(); // 0. Prepare the context for current home if (hid == DataSetupUtility.Home1ID) { fixture.InitHome1TestData(context); } else if (hid == DataSetupUtility.Home2ID) { fixture.InitHome2TestData(context); } else if (hid == DataSetupUtility.Home3ID) { fixture.InitHome3TestData(context); } else if (hid == DataSetupUtility.Home4ID) { fixture.InitHome4TestData(context); } else if (hid == DataSetupUtility.Home5ID) { fixture.InitHome5TestData(context); } var account = context.FinanceAccount.Where(p => p.HomeID == hid && p.Status != (Byte)FinanceAccountStatus.Closed).FirstOrDefault(); var cc = context.FinanceControlCenter.Where(p => p.HomeID == hid).FirstOrDefault(); // var orders = context.FinanceOrder.Where(p => p.HomeID == hid).ToList(); // 1. Buy an asset var control = new FinanceDocumentsController(context); var userclaim = DataSetupUtility.GetClaimForUser(user); var httpctx = UnitTestUtility.GetDefaultHttpContext(provider, userclaim); control.ControllerContext = new ControllerContext() { HttpContext = httpctx }; // 1a. Prepare data var assetbuycontext = new FinanceAssetBuyDocumentCreateContext(); assetbuycontext.AccountOwner = user; assetbuycontext.ControlCenterID = cc.ID; assetbuycontext.Desp = "Test buy in"; // assetbuycontext.ExtraAsset = assetbuycontext.HID = hid; assetbuycontext.IsLegacy = islegacy; assetbuycontext.TranAmount = 2000; assetbuycontext.TranCurr = currency; assetbuycontext.TranDate = new DateTime(2020, 1, 1); assetbuycontext.Items = new List <FinanceDocumentItem>(); if (!islegacy) { var item2 = new FinanceDocumentItem() { ItemID = 1, Desp = "Item 1.1", TranType = 3, TranAmount = 2000, AccountID = account.ID, ControlCenterID = cc.ID, }; assetbuycontext.Items.Add(item2); } assetbuycontext.ExtraAsset = new FinanceAccountExtraAS(); assetbuycontext.ExtraAsset.Name = "Asset to buy"; assetbuycontext.ExtraAsset.CategoryID = context.FinAssetCategories.ToList()[0].ID; assetbuycontext.ExtraAsset.Comment = "Test 1"; var resp = await control.PostAssetBuyDocument(assetbuycontext); var doc = Assert.IsType <CreatedODataResult <FinanceDocument> >(resp).Entity; documentsCreated.Add(doc.ID); if (islegacy) { Assert.True(doc.Items.Count == 1); } else { Assert.True(doc.Items.Count == 2); } var assetacntid = 0; if (!islegacy) { foreach (var docitem in doc.Items) { if (docitem.AccountID != account.ID) { assetacntid = docitem.AccountID; var acnt = context.FinanceAccount.Find(docitem.AccountID); Assert.NotNull(acnt); var acntExtraAsset = context.FinanceAccountExtraAS.Find(docitem.AccountID); Assert.NotNull(acntExtraAsset); Assert.True(acntExtraAsset.RefenceBuyDocumentID == doc.ID); } } } else { // The return result has no account info. var acntExtraAsset = context.FinanceAccountExtraAS.First(p => p.RefenceBuyDocumentID == doc.ID); Assert.NotNull(acntExtraAsset); assetacntid = acntExtraAsset.AccountID; } // Now check in the databse for items var ditems = context.FinanceDocumentItem.Where(p => p.AccountID == assetacntid).ToList(); Assert.True(ditems.Count == 1); // Document item view var ditemview = (from diview in context.FinanceDocumentItemView where diview.AccountID == assetacntid select new { diview.AccountID, diview.Amount, diview.IsExpense } ).ToList(); Assert.True(ditemview.Count == 1); // Check the account group with expense var acntgrpexp = context.FinanceReporAccountGroupAndExpenseView.Where(p => p.AccountID == assetacntid).First(); Assert.NotNull(acntgrpexp); // Check the balance var assetbal = context.FinanceReporAccountGroupView.Where(p => p.AccountID == assetacntid).First(); Assert.NotNull(assetbal); Assert.Equal(2000, assetbal.Balance); // Okay, now sell it var assetsellcontext = new FinanceAssetSellDocumentCreateContext(); assetsellcontext.AssetAccountID = assetacntid; assetsellcontext.ControlCenterID = cc.ID; assetsellcontext.Desp = "Test sell"; assetsellcontext.HID = hid; assetsellcontext.TranAmount = 1000; assetsellcontext.TranCurr = currency; assetsellcontext.TranDate = new DateTime(2021, 1, 1); // Account which received the money assetsellcontext.Items = new List <FinanceDocumentItem>(); var item = new FinanceDocumentItem() { ItemID = 1, Desp = "Item 2.1", TranType = FinanceTransactionType.TranType_AssetSoldoutIncome, TranAmount = 1000, AccountID = account.ID, ControlCenterID = cc.ID, }; assetsellcontext.Items.Add(item); resp = await control.PostAssetSellDocument(assetsellcontext); doc = Assert.IsType <CreatedODataResult <FinanceDocument> >(resp).Entity; documentsCreated.Add(doc.ID); // Last, clear all created objects foreach (var docid in documentsCreated) { this.fixture.DeleteFinanceDocument(context, docid); } if (assetacntid > 0) { this.fixture.DeleteFinanceAccount(context, assetacntid); } await context.SaveChangesAsync(); await context.DisposeAsync(); }