public C1Rescponse Sign([FromBody] SignViewModel model)
        {
            Argument.Require(model != null, "Параметры не заданы.");
            FinanceDocument document = new FinanceDocument(model.DocumentBase64Data, model.DocumentName, model.DocumentMimeType);

            var response = c1Service.Sign(document, model.CertificateId, model.TextForUser);

            return(response);
        }
Exemplo n.º 2
0
        public async Task <IActionResult> Post([FromBody] FinanceDocument document)
        {
            if (!ModelState.IsValid)
            {
                HIHAPIUtility.HandleModalStateError(ModelState);
            }

            // Check document type, DP, Asset, loan document is not allowed
            if (document.DocType == FinanceDocumentType.DocType_AdvancePayment ||
                document.DocType == FinanceDocumentType.DocType_AdvanceReceive ||
                document.DocType == FinanceDocumentType.DocType_AssetBuyIn ||
                document.DocType == FinanceDocumentType.DocType_AssetSoldOut ||
                document.DocType == FinanceDocumentType.DocType_AssetValChg ||
                document.DocType == FinanceDocumentType.DocType_BorrowFrom ||
                document.DocType == FinanceDocumentType.DocType_LendTo)
            {
                throw new BadRequestException("Document type is not allowed");
            }

            // 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 == document.HomeID && p.User == usrName).Count();

            if (hms <= 0)
            {
                throw new UnauthorizedAccessException();
            }

            if (!document.IsValid(this._context))
            {
                return(BadRequest());
            }

            document.CreatedAt = DateTime.Now;
            document.Createdby = usrName;
            _context.FinanceDocument.Add(document);
            await _context.SaveChangesAsync();

            return(Created(document));
        }
Exemplo n.º 3
0
        public C1Rescponse Sign(FinanceDocument document, Guid certificateId, string textForUser)
        {
            Argument.Require(document != null, "Документ пустой.");
            Argument.Require((document.Data?.Length ?? 0) != 0, "Документ пустой.");
            Argument.Require(!string.IsNullOrWhiteSpace(document.Name), "Название документа пустое.");
            Argument.Require(!string.IsNullOrWhiteSpace(document.MimeType), "Mime-type документа пустой.");
            Argument.Require(certificateId != Guid.Empty, "Идентификатор сертификата пустой.");
            Argument.Require(!string.IsNullOrWhiteSpace(textForUser), "Текст для пользователя пустой.");

            var response = c1Repository.Sign(document, certificateId, textForUser);

            return(response);
        }
        /// <summary>
        /// Отправить запрос на подпись документа.
        /// </summary>
        /// <param name="document">Документ.</param>
        /// <param name="certificateId">Идентификатор сертификата пользователя.</param>
        /// <param name="textForUser">текст для пользователя.</param>
        /// <returns>Ответ 1С.</returns>
        public C1Rescponse Sign(FinanceDocument document, Guid certificateId, string textForUser)
        {
            var parameters = new
            {
                certificateGuid = certificateId,
                text            = textForUser,
                callbackUri     = ""
            };

            C1Rescponse <string> response = this.Request <string>("/Sign/Sign", parameters,
                                                                  r => r.AddFileBytes("data", document.Data, document.Name, document.MimeType));

            return(response);
        }
        public C1Rescponse Sign([FromBody] SignViewModel model)
        {
            Argument.Require(model != null, "Параметры не заданы.");
            FinanceDocument document = new FinanceDocument(model.DocumentBase64Data, model.DocumentName, model.DocumentMimeType);

            var response = c1Service.Sign(document, model.CertificateId, model.TextForUser);

            if (response.StatusCode >= STATUS_BAD_MIN)
            {
                return(new C1Rescponse <string>(response));
            }

            return(WaitTillResponse <string>(response.TransactionGuid));
        }
Exemplo n.º 6
0
        public async Task TestCase1()
        {
            string token = await IdentityServerSetup.Instance.GetAccessTokenForUser(DataSetupUtility.UserA, DataSetupUtility.IntegrationTestPassword);

            var clientWithAuth = _factory.CreateClient();

            clientWithAuth.SetBearerToken(token);

            // Step 1. Metadata request
            var metadata = await this._client.GetAsync("/api/$metadata");

            Assert.Equal(HttpStatusCode.OK, metadata.StatusCode);
            var content = await metadata.Content.ReadAsStringAsync();

            if (content.Length > 0)
            {
                // How to verify metadata?
                // TBD.
            }

            // Step 2. Read Home Defines - Non authority case
            var req1 = await this._client.GetAsync("/api/HomeDefines");

            Assert.Equal(HttpStatusCode.Unauthorized, req1.StatusCode);

            // Step 3. Read Home Defines - Authority case
            var resp2 = await clientWithAuth.GetAsync("/api/HomeDefines");

            Assert.True(resp2.IsSuccessStatusCode);
            string result = resp2.Content.ReadAsStringAsync().Result;

            if (!String.IsNullOrEmpty(result))
            {
                JToken outer = JToken.Parse(result);

                // Old way to deserialize the arry
                JArray inner = outer["value"].Value <JArray>();
                var    dfs   = inner.ToObject <List <HomeDefine> >();
                Assert.Equal(2, dfs.Count);

                // For user A, Home1 Is a must
                var bHome1Exist = false;
                foreach (var df in dfs)
                {
                    Assert.NotNull(df);
                    Assert.True(df.ID > 0);
                    Assert.False(String.IsNullOrEmpty(df.Name));
                    Assert.NotNull(df.HomeMembers);
                    if (df.ID == DataSetupUtility.Home1ID)
                    {
                        bHome1Exist = true;
                    }
                }
                Assert.True(bHome1Exist);
            }

            // Step 4. Read home defines - with home members
            resp2 = await clientWithAuth.GetAsync("/api/HomeDefines?$expand=HomeMembers");

            Assert.True(resp2.IsSuccessStatusCode);
            result = resp2.Content.ReadAsStringAsync().Result;
            if (!String.IsNullOrEmpty(result))
            {
                JToken outer = JToken.Parse(result);

                JArray inner = outer["value"].Value <JArray>();
                var    dfs   = inner.ToObject <List <HomeDefine> >();
                Assert.Equal(2, dfs.Count);

                // For user A, Home1 Is a must
                foreach (var df in dfs)
                {
                    Assert.NotNull(df);
                    Assert.True(df.ID > 0);
                    Assert.False(String.IsNullOrEmpty(df.Name));
                    Assert.NotNull(df.HomeMembers);
                    var exist = df.HomeMembers.Single(p => p.User == DataSetupUtility.UserA);
                    Assert.NotNull(exist);
                }
            }

            var hid      = DataSetupUtility.Home1ID;
            var cc1id    = 0;
            var ord1id   = 0;
            var acnt1id  = 0;
            var doc1id   = 0;
            var jsetting = new JsonSerializerSettings();

            jsetting.Converters.Add(new StringEnumConverter());
            jsetting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            jsetting.DateFormatString      = "yyyy-MM-dd";

            // Step 5. Create a control center
            var cc = new FinanceControlCenter()
            {
                HomeID  = hid,
                Name    = "Control Center 1",
                Comment = "Comment 1",
                Owner   = DataSetupUtility.UserA
            };
            var kjson        = JsonConvert.SerializeObject(cc, jsetting);
            var inputContent = new StringContent(kjson, Encoding.UTF8, "application/json");

            resp2 = await clientWithAuth.PostAsync("/api/FinanceControlCenters", inputContent);

            Assert.True(resp2.IsSuccessStatusCode);
            result = resp2.Content.ReadAsStringAsync().Result;
            if (!String.IsNullOrEmpty(result))
            {
                var odatarst = JsonConvert.DeserializeObject <FinanceControlCenter>(result);
                Assert.Equal(odatarst.Name, cc.Name);
                Assert.Equal(odatarst.HomeID, cc.HomeID);
                Assert.Equal(odatarst.Owner, cc.Owner);
                cc1id = odatarst.ID;
                Assert.True(cc1id > 0);
            }

            // Step 6. Create an order
            var ord = new FinanceOrder()
            {
                HomeID  = hid,
                Name    = "Order 1",
                Comment = "Comment 1"
            };
            var srule = new FinanceOrderSRule()
            {
                Order           = ord,
                RuleID          = 1,
                ControlCenterID = cc1id,
                Precent         = 100
            };

            ord.SRule.Add(srule);
            kjson        = JsonConvert.SerializeObject(ord, jsetting);
            inputContent = new StringContent(kjson, Encoding.UTF8, "application/json");
            resp2        = await clientWithAuth.PostAsync("/api/FinanceOrders", inputContent);

            Assert.True(resp2.IsSuccessStatusCode);
            result = resp2.Content.ReadAsStringAsync().Result;
            if (!String.IsNullOrEmpty(result))
            {
                var odatarst = JsonConvert.DeserializeObject <FinanceOrder>(result);
                Assert.Equal(odatarst.Name, ord.Name);
                ord1id = odatarst.ID;
                Assert.True(ord1id > 0);
            }

            // Step 7. Create an account
            var acnt = new FinanceAccount()
            {
                HomeID     = DataSetupUtility.Home1ID,
                Name       = "Account 1",
                CategoryID = FinanceAccountCategory.AccountCategory_Cash,
                Owner      = DataSetupUtility.UserA
            };

            kjson        = JsonConvert.SerializeObject(acnt, jsetting);
            inputContent = new StringContent(kjson, Encoding.UTF8, "application/json");
            resp2        = await clientWithAuth.PostAsync("/api/FinanceAccounts", inputContent);

            Assert.True(resp2.IsSuccessStatusCode);
            result = resp2.Content.ReadAsStringAsync().Result;
            if (!String.IsNullOrEmpty(result))
            {
                var odatarst = JsonConvert.DeserializeObject <FinanceAccount>(result);
                Assert.Equal(odatarst.Name, acnt.Name);
                acnt1id = odatarst.ID;
                Assert.True(acnt1id > 0);
            }

            // Step 7a. Get all accounts
            resp2 = await clientWithAuth.GetAsync("/api/FinanceAccounts?hid=" + hid.ToString());

            Assert.True(resp2.IsSuccessStatusCode);
            result = resp2.Content.ReadAsStringAsync().Result;
            if (!String.IsNullOrEmpty(result))
            {
                //var odatarst = JsonConvert.DeserializeObject<FinanceAccount>(result);
                //Assert.Equal(odatarst.Name, acnt.Name);
                //acnt1id = odatarst.ID;
                //Assert.True(acnt1id > 0);
            }

            // Step 7b. Read one specified account
            resp2 = await clientWithAuth.GetAsync("/api/FinanceAccounts(" + acnt1id.ToString() + ")"); // ?hid=" + hid.ToString());

            Assert.True(resp2.IsSuccessStatusCode);
            result = resp2.Content.ReadAsStringAsync().Result;
            if (!String.IsNullOrEmpty(result))
            {
            }

            // Step 8. Post a document
            var doc = new FinanceDocument()
            {
                DocType  = FinanceDocumentType.DocType_Normal,
                HomeID   = hid,
                TranDate = DateTime.Today,
                Desp     = "First document",
                TranCurr = DataSetupUtility.Home1BaseCurrency,
            };
            var item = new FinanceDocumentItem()
            {
                DocumentHeader  = doc,
                ItemID          = 1,
                Desp            = "Item 1.1",
                TranType        = 2, // Wage
                TranAmount      = 10,
                AccountID       = acnt1id,
                ControlCenterID = cc1id,
            };

            doc.Items.Add(item);
            jsetting.NullValueHandling = NullValueHandling.Ignore;
            kjson        = JsonConvert.SerializeObject(doc, jsetting);
            inputContent = new StringContent(kjson, Encoding.UTF8, "application/json");
            resp2        = await clientWithAuth.PostAsync("/api/FinanceDocuments", inputContent);

            Assert.True(resp2.IsSuccessStatusCode);
            result = resp2.Content.ReadAsStringAsync().Result;
            if (!String.IsNullOrEmpty(result))
            {
                var odatarst = JsonConvert.DeserializeObject <FinanceDocument>(result);
                Assert.Equal(odatarst.Desp, doc.Desp);
                doc1id = odatarst.ID;
                Assert.True(doc1id > 0);
            }

            // Step 9. Create an ADP document
            //var adpcontext = new FinanceADPDocumentCreateContext();
            //adpcontext.DocumentInfo = new FinanceDocument();
            //adpcontext.AccountInfo = new FinanceAccount();
        }
Exemplo n.º 7
0
        public async Task TestCase1(int hid, string currency, string user)
        {
            var context = this.fixture.GetCurrentDataContext();

            // 0a. Prepare the context for other homes to test the filters
            var secondhid = hid;

            if (hid == DataSetupUtility.Home1ID)
            {
                if (user == DataSetupUtility.UserA || user == DataSetupUtility.UserB)
                {
                    secondhid = DataSetupUtility.Home3ID;
                }
                else if (user == DataSetupUtility.UserC)
                {
                    secondhid = DataSetupUtility.Home4ID;
                }
                else if (user == DataSetupUtility.UserD)
                {
                    secondhid = DataSetupUtility.Home5ID;
                }
            }
            else if (hid == DataSetupUtility.Home2ID)
            {
                secondhid = DataSetupUtility.Home3ID;
            }

            if (hid == DataSetupUtility.Home1ID || secondhid == DataSetupUtility.Home1ID)
            {
                fixture.InitHome1TestData(context);
            }
            else if (hid == DataSetupUtility.Home2ID || secondhid == DataSetupUtility.Home2ID)
            {
                fixture.InitHome2TestData(context);
            }
            else if (hid == DataSetupUtility.Home3ID || secondhid == DataSetupUtility.Home3ID)
            {
                fixture.InitHome3TestData(context);
            }
            else if (hid == DataSetupUtility.Home4ID || secondhid == DataSetupUtility.Home4ID)
            {
                fixture.InitHome4TestData(context);
            }
            else if (hid == DataSetupUtility.Home5ID || secondhid == 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 curhmemquery = (from homemem in context.HomeMembers where homemem.HomeID == hid && homemem.User == user select homemem).FirstOrDefault();
            var curhmem      = Assert.IsType <HomeMember>(curhmemquery);
            var existamt     = (from homemem in context.HomeMembers
                                join findoc in context.FinanceDocument
                                on new { homemem.HomeID, homemem.User } equals new { findoc.HomeID, User = user }
                                select findoc.ID).ToList().Count();
            var existamt_curhome = context.FinanceDocument.Where(p => p.HomeID == hid).Count();

            // 1. Create first docs.
            var control   = new FinanceDocumentsController(context);
            var userclaim = DataSetupUtility.GetClaimForUser(user);
            var httpctx   = UnitTestUtility.GetDefaultHttpContext(provider, userclaim);

            control.ControllerContext = new ControllerContext()
            {
                HttpContext = httpctx
            };

            var doc = new FinanceDocument()
            {
                HomeID   = hid,
                DocType  = FinanceDocumentType.DocType_Normal,
                TranCurr = currency,
                Desp     = "Test 1"
            };
            var item = new FinanceDocumentItem()
            {
                DocumentHeader  = doc,
                ItemID          = 1,
                Desp            = "Item 1.1",
                TranType        = 2, // Wage
                TranAmount      = 10,
                AccountID       = account.ID,
                ControlCenterID = cc.ID,
            };

            doc.Items.Add(item);
            var rst = await control.Post(doc);

            Assert.NotNull(rst);
            var rst2 = Assert.IsType <CreatedODataResult <FinanceDocument> >(rst);

            Assert.Equal(rst2.Entity.TranCurr, doc.TranCurr);
            Assert.Equal(rst2.Entity.Desp, doc.Desp);
            var firstdocid = rst2.Entity.ID;

            documentsCreated.Add(firstdocid);
            Assert.True(firstdocid > 0);

            // 2a. Now read the whole orders (without home id)
            var queryUrl     = "http://localhost/api/FinanceDocuments";
            var req          = UnitTestUtility.GetHttpRequest(httpctx, "GET", queryUrl);
            var odatacontext = UnitTestUtility.GetODataQueryContext <FinanceDocument>(this.model);
            var options      = UnitTestUtility.GetODataQueryOptions <FinanceDocument>(odatacontext, req);
            var rst3         = control.Get(options);

            Assert.NotNull(rst3);
            //if (curhmem.IsChild.HasValue && curhmem.IsChild == true)
            //{
            //    existamt = context.FinanceDocument.Where(p => p.Createdby == user).Count();
            //    Assert.Equal(existamt, rst3.Cast<FinanceDocument>().Count());
            //}
            //else
            //{
            //    Assert.Equal(existamt + 1, rst3.Cast<FinanceDocument>().Count());
            //}

            // 2b. Now read the whole orders (with home id)
            queryUrl = "http://localhost/api/FinanceDocuments?$filter=HomeID eq " + hid.ToString();
            req      = UnitTestUtility.GetHttpRequest(httpctx, "GET", queryUrl);
            // odatacontext = UnitTestUtility.GetODataQueryContext<FinanceDocument>(this.model);
            options = UnitTestUtility.GetODataQueryOptions <FinanceDocument>(odatacontext, req);
            rst3    = control.Get(options);
            Assert.NotNull(rst3);
            if (curhmem.IsChild.HasValue && curhmem.IsChild == true)
            {
                existamt_curhome = context.FinanceDocument.Where(p => p.HomeID == hid && p.Createdby == user).Count();
                Assert.Equal(existamt_curhome, rst3.Cast <FinanceDocument>().Count());
            }
            else
            {
                Assert.Equal(existamt_curhome + 1, rst3.Cast <FinanceDocument>().Count());
            }

            // 3. Now create another one!
            doc = new FinanceDocument()
            {
                HomeID   = hid,
                DocType  = FinanceDocumentType.DocType_Normal,
                TranCurr = currency,
                Desp     = "Test 2"
            };
            item = new FinanceDocumentItem()
            {
                DocumentHeader  = doc,
                ItemID          = 1,
                Desp            = "Item 2.1",
                TranType        = 2, // Wage
                TranAmount      = 10,
                AccountID       = account.ID,
                ControlCenterID = cc.ID
            };
            doc.Items.Add(item);
            rst = await control.Post(doc);

            Assert.NotNull(rst);
            rst2 = Assert.IsType <CreatedODataResult <FinanceDocument> >(rst);
            Assert.Equal(rst2.Entity.TranCurr, doc.TranCurr);
            Assert.Equal(rst2.Entity.Desp, doc.Desp);
            // documentsCreated.Add(rst2.Entity);
            var seconddocid = rst2.Entity.ID;

            Assert.True(seconddocid > 0);

            // 4a. Change one document - add new document item
            doc.Desp = "Change Test";
            doc.Items.Add(new FinanceDocumentItem
            {
                DocumentHeader  = doc,
                ItemID          = 2,
                Desp            = "Item 2.2",
                TranType        = 2, // Wage
                TranAmount      = 20,
                AccountID       = account.ID,
                ControlCenterID = cc.ID
            });
            rst = await control.Put(seconddocid, doc);

            Assert.NotNull(rst);
            var rst4 = Assert.IsType <UpdatedODataResult <FinanceDocument> >(rst);

            Assert.Equal(doc.Desp, rst4.Entity.Desp);
            Assert.Equal(2, rst4.Entity.Items.Count);
            Assert.Equal("Item 2.1", rst4.Entity.Items.First(p => p.ItemID == 1).Desp);
            Assert.Equal("Item 2.2", rst4.Entity.Items.First(p => p.ItemID == 2).Desp);

            // 4b. Change one document - remove document item
            var itemidx = doc.Items.First(p => p.ItemID == 2);

            doc.Items.Remove(item);
            rst = await control.Put(seconddocid, doc);

            Assert.NotNull(rst);
            rst4 = Assert.IsType <UpdatedODataResult <FinanceDocument> >(rst);
            Assert.Equal(1, rst4.Entity.Items.Count);
            // Assert.Equal("Item 2.1", rst4.Entity.Items.First(p => p.ItemID == 1).Desp);

            // 5. Delete the second document
            var rst5 = await control.Delete(seconddocid);

            Assert.NotNull(rst5);
            var rst6 = Assert.IsType <StatusCodeResult>(rst5);

            Assert.Equal(204, rst6.StatusCode);
            Assert.Equal(0, context.FinanceDocumentItem.Where(p => p.DocID == seconddocid).Count());

            // 6. Now read the whole documents
            rst3 = control.Get(options);
            Assert.NotNull(rst3);
            if (curhmem.IsChild.HasValue && curhmem.IsChild == true)
            {
                existamt_curhome = context.FinanceDocument.Where(p => p.HomeID == hid && p.Createdby == user).Count();
                Assert.Equal(existamt_curhome, rst3.Cast <FinanceDocument>().Count());
            }
            else
            {
                Assert.Equal(existamt_curhome + 1, rst3.Cast <FinanceDocument>().Count());
            }

            // Last, clear all created objects
            CleanupCreatedEntries();
            await context.SaveChangesAsync();

            await context.DisposeAsync();
        }
Exemplo n.º 8
0
        public async Task <IActionResult> PostAssetValueChangeDocument([FromBody] FinanceAssetRevaluationDocumentCreateContext createContext)
        {
            if (!ModelState.IsValid)
            {
                HIHAPIUtility.HandleModalStateError(ModelState);
            }

            if (createContext == null)
            {
                throw new BadRequestException("No data is inputted");
            }
            if (createContext.HID <= 0)
            {
                throw new BadRequestException("Not HID inputted");
            }
            if (createContext.AssetAccountID <= 0)
            {
                throw new BadRequestException("Asset Account is invalid");
            }
            if (createContext.Items.Count != 1)
            {
                throw new BadRequestException("Items count is not correct");
            }

            // 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_AssetValChg;
            vmFIDoc.Desp     = createContext.Desp;
            vmFIDoc.TranDate = createContext.TranDate;
            vmFIDoc.HomeID   = createContext.HID;
            vmFIDoc.TranCurr = createContext.TranCurr;

            Decimal totalAmount = 0;
            Int32?  rlTranType  = null;

            foreach (var di in createContext.Items)
            {
                if (di.ItemID <= 0 || di.TranAmount == 0 ||
                    di.AccountID != createContext.AssetAccountID ||
                    (di.TranType != FinanceTransactionType.TranType_AssetValueIncrease &&
                     di.TranType != FinanceTransactionType.TranType_AssetValueDecrease) ||
                    (di.ControlCenterID <= 0 && di.OrderID <= 0))
                {
                    return(BadRequest("Invalid input data in items!"));
                }

                if (rlTranType == null)
                {
                    rlTranType = di.TranType;
                }
                else
                {
                    if (rlTranType.Value != di.TranType)
                    {
                        return(BadRequest("Cannot support different trantype"));
                    }
                }

                totalAmount += di.TranAmount;

                vmFIDoc.Items.Add(di);
            }

            // Basic check - TBD
            //try
            //{
            //    FinanceDocumentController.FinanceDocumentBasicCheck(vmFIDoc);
            //}
            //catch(Exception exp)
            //{
            //}
            // Perfrom the doc. validation
            //await FinanceDocumentsController.FinanceDocumentBasicValidationAsync(vmFIDoc, conn);

            // Additional check 1.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");
            }
            // Additional check 2. 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");
            }
            // Additional 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");
            }
            // Additional check 4: the balance with the inputted value
            var nCmpRst = Decimal.Compare(query3, totalAmount);

            if (nCmpRst > 0)
            {
                if (rlTranType.Value != FinanceTransactionType.TranType_AssetValueDecrease)
                {
                    throw new BadRequestException("Tran type is wrong");
                }
            }
            else if (nCmpRst < 0)
            {
                if (rlTranType.Value != FinanceTransactionType.TranType_AssetValueIncrease)
                {
                    throw new BadRequestException("Tran type is wrong");
                }
            }
            else if (nCmpRst == 0)
            {
                throw new BadRequestException("Current balance equals to new value");
            }

            // Update the database
            var errorString = "";
            var errorOccur  = false;
            var origdocid   = 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;

                    vmFIDoc = docEntity.Entity;

                    transaction.Commit();
                }
                catch (Exception exp)
                {
                    errorOccur  = true;
                    errorString = exp.Message;
                    transaction.Rollback();
                }
            }

            if (errorOccur)
            {
                throw new BadRequestException(errorString);
            }

            return(Created(vmFIDoc));
        }
Exemplo n.º 9
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));
        }
Exemplo n.º 10
0
        public async Task <IActionResult> Put([FromODataUri] int key, [FromBody] FinanceDocument update)
        {
            if (!ModelState.IsValid)
            {
                HIHAPIUtility.HandleModalStateError(ModelState);
            }

            if (key != update.ID)
            {
                throw new BadRequestException("Inputted ID mismatched");
            }

            // 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 == update.HomeID && p.User == usrName).Count();

            if (hms <= 0)
            {
                throw new UnauthorizedAccessException();
            }

            if (!update.IsValid(this._context))
            {
                return(BadRequest());
            }

            update.UpdatedAt             = DateTime.Now;
            update.Updatedby             = usrName;
            _context.Entry(update).State = EntityState.Modified;

            // Items
            var itemsInDB = _context.FinanceDocumentItem.Where(p => p.DocID == update.ID).ToList();

            foreach (var ditem in update.Items)
            {
                var itemindb = itemsInDB.Find(p => p.DocID == update.ID && p.ItemID == ditem.ItemID);
                if (itemindb == null)
                {
                    _context.FinanceDocumentItem.Add(ditem);
                }
                else
                {
                    // Update
                    _context.Entry(itemindb).State = EntityState.Modified;
                }
            }
            foreach (var ditem in itemsInDB)
            {
                var nitem = update.Items.FirstOrDefault(p => p.DocID == update.ID && p.ItemID == ditem.ItemID);
                if (nitem == null)
                {
                    _context.FinanceDocumentItem.Remove(ditem);
                }
            }

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException exp)
            {
                if (!_context.FinanceDocument.Any(p => p.ID == key))
                {
                    return(NotFound());
                }
                else
                {
                    throw new DBOperationException(exp.Message);
                }
            }

            return(Updated(update));
        }
Exemplo n.º 11
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));
        }
Exemplo n.º 12
0
        public async Task <IActionResult> PostDocument([FromBody] FinanceTmpDPDocumentPostContext context)
        {
            // User
            String usrName = String.Empty;

            try
            {
                usrName = HIHAPIUtility.GetUserID(this);
                if (String.IsNullOrEmpty(usrName))
                {
                    throw new UnauthorizedAccessException();
                }
            }
            catch
            {
                throw new UnauthorizedAccessException();
            }

            var tpdoc = _context.FinanceTmpDPDocument
                        .Where(p => p.DocumentID == context.DocumentID && p.AccountID == context.AccountID && p.HomeID == context.HomeID)
                        .SingleOrDefault();

            if (tpdoc == null)
            {
                return(NotFound());
            }

            // Check 1: Home ID
            var hms = from hmem in _context.HomeMembers
                      where hmem.User == usrName && hmem.HomeID == tpdoc.HomeID
                      select new { HomeID = hmem.HomeID } into hids
            join homedefs in _context.HomeDefines
            on hids.HomeID equals homedefs.ID
                select new { HomeID = homedefs.ID, BaseCurrency = homedefs.BaseCurrency };

            if (hms.Count() != 1)
            {
                throw new UnauthorizedAccessException();
            }
            var homes = hms.ToList();

            // Check 2: Document posted already?
            if (tpdoc.ReferenceDocumentID.HasValue && tpdoc.ReferenceDocumentID.Value > 0)
            {
                throw new BadRequestException("Tmp Doc not existed yet or has been posted");
            }
            if (!tpdoc.ControlCenterID.HasValue && !tpdoc.OrderID.HasValue)
            {
                throw new BadRequestException("Tmp doc lack of control center or order");
            }
            if (tpdoc.TranAmount == 0)
            {
                throw new BadRequestException("Tmp doc lack of amount");
            }

            // Left items
            var dpAccount = _context.FinanceAccount.Where(p => p.ID == context.AccountID && p.HomeID == context.HomeID).SingleOrDefault();

            if (dpAccount == null)
            {
                throw new BadRequestException("Cannot find Account");
            }
            else if (!(dpAccount.Status == null || dpAccount.Status == (Byte)FinanceAccountStatus.Normal))
            {
                throw new BadRequestException("Account status is not Normal");
            }

            var leftItemsCnt = _context.FinanceTmpDPDocument
                               .Where(p => p.AccountID == context.AccountID && p.HomeID == context.HomeID && p.DocumentID != context.DocumentID && p.ReferenceDocumentID == null)
                               .Count();

            // Save it to normal doc.
            var findoc = new FinanceDocument();

            findoc.Desp    = tpdoc.Description;
            findoc.DocType = FinanceDocumentType.DocType_Normal;
            findoc.HomeID  = tpdoc.HomeID;
            //findoc.TranAmount = vmTmpDoc.TranAmount;
            findoc.TranCurr  = homes[0].BaseCurrency;
            findoc.TranDate  = tpdoc.TransactionDate;
            findoc.CreatedAt = DateTime.Now;
            var findocitem = new FinanceDocumentItem
            {
                AccountID = tpdoc.AccountID
            };

            if (tpdoc.ControlCenterID.HasValue)
            {
                findocitem.ControlCenterID = tpdoc.ControlCenterID.Value;
            }
            if (tpdoc.OrderID.HasValue)
            {
                findocitem.OrderID = tpdoc.OrderID.Value;
            }
            findocitem.Desp       = tpdoc.Description;
            findocitem.ItemID     = 1;
            findocitem.TranAmount = tpdoc.TranAmount;
            findocitem.TranType   = tpdoc.TransactionType;
            findoc.Items.Add(findocitem);

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

            using (var transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    // 1. Create the document
                    findoc.CreatedAt = DateTime.Now;
                    findoc.Createdby = usrName;
                    var docEntity = _context.FinanceDocument.Add(findoc);
                    _context.SaveChanges();
                    origdocid = docEntity.Entity.ID;

                    // 2. Update the tmp doc
                    tpdoc.ReferenceDocumentID = origdocid;
                    tpdoc.UpdatedAt           = DateTime.Now;
                    tpdoc.Updatedby           = usrName;
                    _context.FinanceTmpDPDocument.Update(tpdoc);
                    _context.SaveChanges();

                    // 3. Close DP account
                    if (leftItemsCnt == 0)
                    {
                        dpAccount.Status    = (Byte)FinanceAccountStatus.Closed;
                        dpAccount.Updatedby = usrName;
                        dpAccount.UpdatedAt = DateTime.Now;
                        _context.FinanceAccount.Update(dpAccount);
                        _context.SaveChanges();
                    }

                    findoc = docEntity.Entity;

                    await transaction.CommitAsync();
                }
                catch (Exception exp)
                {
                    errorOccur  = true;
                    errorString = exp.Message;
                    transaction.Rollback();
                }
            }

            if (errorOccur)
            {
                throw new DBOperationException(errorString);
            }

            return(Created(findoc));
        }
Exemplo n.º 13
0
        public async Task <IActionResult> PostRepayDocument([FromBody] FinanceLoanRepayDocumentCreateContext createContext)
        {
            if (!ModelState.IsValid)
            {
                HIHAPIUtility.HandleModalStateError(ModelState);
            }

            // Checks
            // Check 0: Input data check
            if (createContext.HomeID <= 0 ||
                createContext.LoanTemplateDocumentID <= 0 ||
                createContext.DocumentInfo == null ||
                createContext.DocumentInfo.DocType != FinanceDocumentType.DocType_Repay)
            {
                throw new BadRequestException("Invalid inputted data");
            }

            // Check 1: User
            String usrName = String.Empty;

            try
            {
                usrName = HIHAPIUtility.GetUserID(this);
                if (String.IsNullOrEmpty(usrName))
                {
                    throw new UnauthorizedAccessException();
                }
            }
            catch
            {
                throw new UnauthorizedAccessException();
            }

            // Check 1: Home ID
            var hms = _context.HomeMembers.Where(p => p.HomeID == createContext.HomeID && p.User == usrName).Count();

            if (hms <= 0)
            {
                throw new UnauthorizedAccessException();
            }

            // Check 2: Template doc
            var docLoanTmp = _context.FinanceTmpLoanDocument
                             .Where(p => p.DocumentID == createContext.LoanTemplateDocumentID)
                             .FirstOrDefault();

            if (docLoanTmp == null ||
                docLoanTmp.ReferenceDocumentID > 0)
            {
                throw new BadRequestException("Invalid loan template ID or doc has been posted");
            }
            if (!docLoanTmp.ControlCenterID.HasValue && !docLoanTmp.OrderID.HasValue)
            {
                throw new BadRequestException("Tmp doc lack of control center or order");
            }
            if (docLoanTmp.TransactionAmount == 0)
            {
                throw new BadRequestException("Tmp doc lack of amount");
            }

            // Check 3: Account
            var loanAccountHeader = _context.FinanceAccount.Where(p => p.ID == docLoanTmp.AccountID).FirstOrDefault();

            if (loanAccountHeader == null ||
                loanAccountHeader.Status != (Byte)FinanceAccountStatus.Normal ||
                !(loanAccountHeader.CategoryID == FinanceAccountCategory.AccountCategory_BorrowFrom ||
                  loanAccountHeader.CategoryID == FinanceAccountCategory.AccountCategory_LendTo)
                )
            {
                throw new BadRequestException("Account not exist or account has wrong status or account has wrong category");
            }
            var loanAccountExtra = _context.FinanceAccountExtraLoan.Where(p => p.AccountID == loanAccountHeader.ID).FirstOrDefault();

            if (loanAccountExtra == null)
            {
                throw new BadRequestException("Account is not a valid loan account");
            }

            // Check 4: Check amounts
            int     ninvaliditems = 0;
            Decimal acntBalance   = 0M;
            // Balance
            var acntBalInfo = _context.FinanceReporAccountGroupAndExpenseView.Where(p => p.AccountID == loanAccountHeader.ID).ToList();

            if (acntBalInfo.Count > 0)
            {
                acntBalance = 0;
                acntBalInfo.ForEach(action =>
                {
                    if (action.IsExpense)
                    {
                        acntBalance += action.Balance;
                    }
                    else
                    {
                        acntBalance += action.Balance;
                    }
                });
            }
            else
            {
                throw new BadRequestException("No balance");
            }

            // Only four tran. types are allowed
            if (loanAccountHeader.CategoryID == FinanceAccountCategory.AccountCategory_BorrowFrom)
            {
                ninvaliditems = createContext.DocumentInfo.Items.Where(item => item.TranType != FinanceTransactionType.TranType_InterestOut &&
                                                                       item.TranType != FinanceTransactionType.TranType_RepaymentOut &&
                                                                       item.TranType != FinanceTransactionType.TranType_RepaymentIn)
                                .Count();
            }
            else if (loanAccountHeader.CategoryID == FinanceAccountCategory.AccountCategory_LendTo)
            {
                ninvaliditems = createContext.DocumentInfo.Items.Where(item => item.TranType != FinanceTransactionType.TranType_InterestIn &&
                                                                       item.TranType != FinanceTransactionType.TranType_RepaymentOut &&
                                                                       item.TranType != FinanceTransactionType.TranType_RepaymentIn)
                                .Count();
            }
            if (ninvaliditems > 0)
            {
                throw new BadRequestException("Items with invalid tran type");
            }

            // Check the amount
            decimal totalOut = createContext.DocumentInfo.Items
                               .Where(item => item.TranType == FinanceTransactionType.TranType_RepaymentOut)
                               .Sum(item2 => item2.TranAmount);
            decimal totalIn = createContext.DocumentInfo.Items
                              .Where(item => item.TranType == FinanceTransactionType.TranType_RepaymentIn)
                              .Sum(item2 => item2.TranAmount);

            //decimal totalintOut = repaydoc.Items.Where(item => (item.TranType == FinanceTranTypeViewModel.TranType_InterestOut)).Sum(item2 => item2.TranAmount);
            // New account balance
            if (loanAccountHeader.CategoryID == FinanceAccountCategory.AccountCategory_LendTo)
            {
                acntBalance -= totalOut;
            }
            else if (loanAccountHeader.CategoryID == FinanceAccountCategory.AccountCategory_BorrowFrom)
            {
                acntBalance += totalIn;
            }
            if (totalOut != totalIn)
            {
                throw new BadRequestException("Amount is not equal!");
            }

            // The post here is:
            // 1. Post a repayment document with the content from this template doc
            // 2. Update the template doc with REFDOCID
            // 3. If the account balance is zero, close the account;

            // Database update
            var             errorString = "";
            var             errorOccur  = false;
            var             origdocid   = 0;
            FinanceDocument findoc      = null;

            using (var transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    // 1. Create the document
                    createContext.DocumentInfo.Createdby = usrName;
                    createContext.DocumentInfo.CreatedAt = DateTime.Now;
                    var docEntity = _context.FinanceDocument.Add(createContext.DocumentInfo);
                    _context.SaveChanges();
                    origdocid = docEntity.Entity.ID;

                    // 2. Update the tmp doc
                    docLoanTmp.ReferenceDocumentID = origdocid;
                    docLoanTmp.UpdatedAt           = DateTime.Now;
                    docLoanTmp.Updatedby           = usrName;
                    _context.FinanceTmpLoanDocument.Update(docLoanTmp);
                    _context.SaveChanges();

                    // 3. In case balance is zero, update the account status
                    if (Decimal.Compare(acntBalance, 0) == 0)
                    {
                        loanAccountHeader.Status    = (Byte)FinanceAccountStatus.Closed;
                        loanAccountHeader.Updatedby = usrName;
                        loanAccountHeader.UpdatedAt = DateTime.Now;
                        _context.FinanceAccount.Update(loanAccountHeader);
                        _context.SaveChanges();
                    }

                    findoc = docEntity.Entity;

                    await transaction.CommitAsync();
                }
                catch (Exception exp)
                {
                    errorOccur  = true;
                    errorString = exp.Message;
                    transaction.Rollback();
                }
            }

            if (errorOccur)
            {
                throw new DBOperationException(errorString);
            }

            return(Created(findoc));
        }