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