Пример #1
0
        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();
        }