예제 #1
0
        public static async Task <long> PostAsync(string tenant, TransactionPosting model, LoginView meta)
        {
            foreach (var item in model.Details)
            {
                if (item.Debit > 0 && item.Credit > 0)
                {
                    throw new InvalidOperationException(I18N.InvalidData);
                }

                if (item.Debit == 0 && item.Credit == 0)
                {
                    throw new InvalidOperationException(I18N.InvalidData);
                }

                if (item.Credit < 0 || item.Debit < 0)
                {
                    throw new InvalidOperationException(I18N.InvalidData);
                }

                if (item.Credit > 0)
                {
                    if (await Accounts.IsCashAccountAsync(tenant, item.AccountNumber).ConfigureAwait(true))
                    {
                        if (await CashRepositories.GetBalanceAsync(tenant, item.CashRepositoryCode, item.CurrencyCode).ConfigureAwait(true) < item.Credit)
                        {
                            throw new InvalidOperationException(I18N.InsufficientBalanceInCashRepository);
                        }
                    }
                }
            }

            decimal drTotal = (from detail in model.Details select detail.LocalCurrencyDebit).Sum();
            decimal crTotal = (from detail in model.Details select detail.LocalCurrencyCredit).Sum();

            if (drTotal != crTotal)
            {
                throw new InvalidOperationException(I18N.ReferencingSidesNotEqual);
            }

            int decimalPlaces = CultureManager.GetCurrencyDecimalPlaces();

            if ((from detail in model.Details
                 where
                 decimal.Round(detail.Credit * detail.ExchangeRate, decimalPlaces) !=
                 decimal.Round(detail.LocalCurrencyCredit, decimalPlaces) ||
                 decimal.Round(detail.Debit * detail.ExchangeRate, decimalPlaces) !=
                 decimal.Round(detail.LocalCurrencyDebit, decimalPlaces)
                 select detail).Any())
            {
                throw new InvalidOperationException(I18N.ReferencingSidesNotEqual);
            }


            long tranId = await TransactionPostings.AddAsync(tenant, meta, model).ConfigureAwait(true);

            return(tranId);
        }
예제 #2
0
        public async Task <ActionResult> PostAsync(TransactionPosting model)
        {
            if (!this.ModelState.IsValid)
            {
                return(this.InvalidModelState(this.ModelState));
            }

            try
            {
                var meta = await AppUsers.GetCurrentAsync().ConfigureAwait(true);

                long tranId = await JournalEntries.PostAsync(this.Tenant, model, meta).ConfigureAwait(true);

                return(this.Ok(tranId));
            }
            catch (Exception ex)
            {
                return(this.Failed(ex.Message, HttpStatusCode.InternalServerError));
            }
        }
예제 #3
0
        public static async Task <long> AddAsync(string tenant, LoginView userInfo, TransactionPosting model)
        {
            long   transactionMasterId = 0;
            string bookName            = "Journal Entry";
            bool   canPost             = await CanPostTransactionAsync(tenant, userInfo.LoginId, userInfo.UserId, userInfo.OfficeId, bookName, model.ValueDate).ConfigureAwait(false);

            if (!canPost)
            {
                return(transactionMasterId);
            }


            using (var db = DbProvider.Get(FrapidDbServer.GetConnectionString(tenant), tenant).GetDatabase())
            {
                try
                {
                    db.BeginTransaction();

                    var master = new TransactionMaster
                    {
                        Book                 = bookName,
                        ValueDate            = model.ValueDate,
                        BookDate             = model.BookDate,
                        TransactionTs        = DateTimeOffset.UtcNow,
                        TransactionCode      = string.Empty,
                        LoginId              = userInfo.LoginId,
                        UserId               = userInfo.UserId,
                        OfficeId             = userInfo.OfficeId,
                        CostCenterId         = model.CostCenterId,
                        ReferenceNumber      = model.ReferenceNumber,
                        StatementReference   = string.Empty,
                        VerificationStatusId = 0,
                        VerificationReason   = string.Empty,
                        AuditUserId          = userInfo.UserId,
                        AuditTs              = DateTimeOffset.UtcNow,
                        Deleted              = false
                    };

                    var insertedId =
                        await
                        db.InsertAsync("finance.transaction_master", "transaction_master_id", true, master)
                        .ConfigureAwait(true);

                    transactionMasterId = insertedId.To <long>();


                    foreach (var line in model.Details)
                    {
                        decimal amountInCurrency;
                        string  tranType;
                        decimal amountInLocalCurrency;

                        if (line.Credit.Equals(0) && line.Debit > 0)
                        {
                            tranType              = "Dr";
                            amountInCurrency      = line.Debit;
                            amountInLocalCurrency = line.LocalCurrencyDebit;
                        }
                        else
                        {
                            tranType              = "Cr";
                            amountInCurrency      = line.Credit;
                            amountInLocalCurrency = line.LocalCurrencyCredit;
                        }


                        var detail = new TransactionDetail
                        {
                            TransactionMasterId = transactionMasterId,
                            ValueDate           = model.ValueDate,
                            BookDate            = model.BookDate,
                            TranType            = tranType,
                            AccountId           = await Accounts.GetAccountIdByAccountNumberAsync(tenant, line.AccountNumber).ConfigureAwait(false),
                            StatementReference  = line.StatementReference,
                            CashRepositoryId    = await CashRepositories.GetCashRepositoryIdByCashRepositoryCodeAsync(tenant, line.CashRepositoryCode).ConfigureAwait(false),
                            CurrencyCode        = line.CurrencyCode,
                            AmountInCurrency    = amountInCurrency,
                            OfficeId            = userInfo.OfficeId,
                            LocalCurrencyCode   = userInfo.CurrencyCode,
                            Er = line.ExchangeRate,
                            AmountInLocalCurrency = amountInLocalCurrency,
                            AuditUserId           = userInfo.UserId,
                            AuditTs = DateTimeOffset.UtcNow
                        };

                        await db.InsertAsync("finance.transaction_details", "transaction_detail_id", true, detail).ConfigureAwait(false);
                    }

                    if (model.Attachemnts != null && model.Attachemnts.Count > 0)
                    {
                        foreach (var item in model.Attachemnts)
                        {
                            var document = new TransactionDocument
                            {
                                TransactionMasterId = transactionMasterId,
                                OriginalFileName    = item.OriginalFileName,
                                FileExtension       = item.FileExtension,
                                FilePath            = item.FilePath,
                                Memo        = item.Memo,
                                AuditUserId = userInfo.UserId,
                                AuditTs     = DateTimeOffset.UtcNow,
                                Deleted     = false
                            };

                            await db.InsertAsync("finance.transaction_documents", "document_id", true, document).ConfigureAwait(false);
                        }
                    }

                    var sql = new Sql("SELECT * FROM finance.auto_verify(@0::bigint, @1::integer)", transactionMasterId, userInfo.UserId);
                    await db.ExecuteAsync(sql).ConfigureAwait(false);

                    db.CompleteTransaction();
                }
                catch (Exception)
                {
                    db.AbortTransaction();
                    throw;
                }
            }

            return(transactionMasterId);
        }
예제 #4
0
        public async Task <ActionResult> PostAsync(TransactionPosting model)
        {
            if (!this.ModelState.IsValid)
            {
                return(this.InvalidModelState(this.ModelState));
            }



            foreach (var item in model.Details)
            {
                if (item.Debit > 0 && item.Credit > 0)
                {
                    throw new InvalidOperationException(I18N.InvalidData);
                }

                if (item.Debit == 0 && item.Credit == 0)
                {
                    throw new InvalidOperationException(I18N.InvalidData);
                }

                if (item.Credit < 0 || item.Debit < 0)
                {
                    throw new InvalidOperationException(I18N.InvalidData);
                }

                if (item.Credit > 0)
                {
                    if (await Accounts.IsCashAccountAsync(this.Tenant, item.AccountNumber).ConfigureAwait(true))
                    {
                        if (
                            await CashRepositories.GetBalanceAsync(this.Tenant, item.CashRepositoryCode,
                                                                   item.CurrencyCode).ConfigureAwait(true) < item.Credit)
                        {
                            throw new InvalidOperationException(I18N.InsufficientBalanceInCashRepository);
                        }
                    }
                }
            }

            decimal drTotal = (from detail in model.Details select detail.LocalCurrencyDebit).Sum();
            decimal crTotal = (from detail in model.Details select detail.LocalCurrencyCredit).Sum();

            if (drTotal != crTotal)
            {
                throw new InvalidOperationException(I18N.ReferencingSidesNotEqual);
            }

            int decimalPlaces = CultureManager.GetCurrencyDecimalPlaces();

            if ((from detail in model.Details
                 where
                 decimal.Round(detail.Credit * detail.ExchangeRate, decimalPlaces) !=
                 decimal.Round(detail.LocalCurrencyCredit, decimalPlaces) ||
                 decimal.Round(detail.Debit * detail.ExchangeRate, decimalPlaces) !=
                 decimal.Round(detail.LocalCurrencyDebit, decimalPlaces)
                 select detail).Any())
            {
                throw new InvalidOperationException(I18N.ReferencingSidesNotEqual);
            }

            var user = await AppUsers.GetCurrentAsync().ConfigureAwait(true);

            try
            {
                long tranId = await TransacitonPostings.AddAsync(this.Tenant, user, model).ConfigureAwait(true);

                return(this.Ok(tranId));
            }
            catch (Exception ex)
            {
                return(this.Failed(ex.Message, HttpStatusCode.InternalServerError));
            }
        }