Ejemplo n.º 1
0
        public async Task <IActionResult> PostAssetBuyDocument([FromBody] FinanceAssetBuyDocumentCreateContext createContext)
        {
            if (!ModelState.IsValid)
            {
                HIHAPIUtility.HandleModalStateError(ModelState);
            }

            if (createContext == null || createContext.ExtraAsset == null)
            {
                throw new BadRequestException("No data is inputted");
            }
            if (createContext.HID <= 0)
            {
                throw new BadRequestException("Not HID 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();
            }

            // Do basic checks
            if (String.IsNullOrEmpty(createContext.TranCurr) || String.IsNullOrEmpty(createContext.ExtraAsset.Name))
            {
                throw new BadRequestException("Invalid input data");
            }
            if (createContext.IsLegacy.HasValue && createContext.IsLegacy.Value)
            {
                if (createContext.Items.Count > 0)
                {
                    throw new BadRequestException("Invalid input data");
                }
            }
            else
            {
                if (createContext.Items.Count <= 0)
                {
                    throw new BadRequestException("Invalid input data");
                }
            }

            foreach (var di in createContext.Items)
            {
                if (di.TranAmount == 0 || di.AccountID <= 0 || di.TranType <= 0 || (di.ControlCenterID <= 0 && di.OrderID <= 0))
                {
                    throw new BadRequestException("Invalid input data in items!");
                }
            }

            // Construct the Account
            var vmAccount = new FinanceAccount();

            vmAccount.HomeID                   = createContext.HID;
            vmAccount.Name                     = createContext.ExtraAsset.Name;
            vmAccount.Status                   = (Byte)FinanceAccountStatus.Normal;
            vmAccount.CategoryID               = FinanceAccountCategory.AccountCategory_Asset;
            vmAccount.ExtraAsset               = new FinanceAccountExtraAS();
            vmAccount.Owner                    = createContext.AccountOwner;
            vmAccount.Comment                  = createContext.ExtraAsset.Comment;
            vmAccount.ExtraAsset.Name          = createContext.ExtraAsset.Name;
            vmAccount.ExtraAsset.Comment       = createContext.ExtraAsset.Comment;
            vmAccount.ExtraAsset.CategoryID    = createContext.ExtraAsset.CategoryID;
            vmAccount.ExtraAsset.AccountHeader = vmAccount;

            // Construct the Doc.
            var vmFIDoc = new FinanceDocument();

            vmFIDoc.DocType  = FinanceDocumentType.DocType_AssetBuyIn;
            vmFIDoc.Desp     = createContext.Desp;
            vmFIDoc.TranDate = createContext.TranDate;
            vmFIDoc.HomeID   = createContext.HID;
            vmFIDoc.TranCurr = createContext.TranCurr;

            var maxItemID = 0;

            if (createContext.IsLegacy.HasValue && createContext.IsLegacy.Value)
            {
                // Legacy account...
            }
            else
            {
                Decimal totalAmt = 0;
                foreach (var di in createContext.Items)
                {
                    if (di.ItemID <= 0 || di.TranAmount == 0 || di.AccountID <= 0 ||
                        (di.ControlCenterID <= 0 && di.OrderID <= 0))
                    {
                        throw new BadRequestException("Invalid input data in items!");
                    }

                    // Todo: new check the tran. type is an expense!

                    totalAmt += di.TranAmount;
                    vmFIDoc.Items.Add(di);

                    if (maxItemID < di.ItemID)
                    {
                        maxItemID = di.ItemID;
                    }
                }

                if (totalAmt != createContext.TranAmount)
                {
                    throw new BadRequestException("Amount is not even");
                }
            }

            // Database update
            var errorString    = "";
            var errorOccur     = false;
            var origdocid      = 0;
            var assetaccountid = 0;

            using (var transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    // 1. Create the document
                    vmFIDoc.Createdby = usrName;
                    vmFIDoc.CreatedAt = DateTime.Now;
                    var docEntity = _context.FinanceDocument.Add(vmFIDoc);
                    await _context.SaveChangesAsync();

                    origdocid = docEntity.Entity.ID;

                    // 2, Create the account
                    vmAccount.ExtraAsset.RefenceBuyDocumentID = origdocid;
                    vmAccount.CreatedAt = DateTime.Now;
                    vmAccount.Createdby = usrName;
                    var acntEntity = _context.FinanceAccount.Add(vmAccount);
                    await _context.SaveChangesAsync();

                    assetaccountid = acntEntity.Entity.ID;

                    // 3. Update the document by adding one more item
                    var nitem = new FinanceDocumentItem();
                    nitem.ItemID     = ++maxItemID;
                    nitem.AccountID  = assetaccountid;
                    nitem.TranAmount = createContext.TranAmount;
                    nitem.Desp       = vmFIDoc.Desp;
                    nitem.TranType   = FinanceTransactionType.TranType_OpeningAsset;
                    if (createContext.ControlCenterID.HasValue)
                    {
                        nitem.ControlCenterID = createContext.ControlCenterID.Value;
                    }
                    if (createContext.OrderID.HasValue)
                    {
                        nitem.OrderID = createContext.OrderID.Value;
                    }
                    nitem.DocumentHeader = vmFIDoc;
                    docEntity.Entity.Items.Add(nitem);

                    docEntity.State = EntityState.Modified;

                    await _context.SaveChangesAsync();

                    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();
        }