public IOperationResult <AccountingEntry> UpdateAccounting(AccountingEntry accountingEntry) { IOperationResult <AccountingEntry> result = _accountEntryRepository.Update(accountingEntry); _accountEntryRepository.Save(); return(result); }
public IOperationResult <bool> DeleteAccountingEntry(long entryId) { try { var debitCredit = _debitCreditEntryRepository.Find(entryId).Entity; if (debitCredit == null) { return(BasicOperationResult <bool> .Fail("EntryNotFound")); } _debitCreditEntryRepository.Delete(debitCredit); AccountingEntry debitEntry = _accountEntryRepository.Find(e => e.Id == debitCredit.DebitEntryId); _accountEntryRepository.Remove(debitEntry); AccountingEntry creditEntry = _accountEntryRepository.Find(e => e.Id == debitCredit.CreditEntryId); _accountEntryRepository.Remove(creditEntry); _accountEntryRepository.Save(); return(BasicOperationResult <bool> .Ok(true)); } catch (System.Exception ex) { return(BasicOperationResult <bool> .Fail(ex.Message)); } }
/// <summary> /// Handles the case when sale order is using credit /// </summary> /// <param name="db"></param> /// <param name="so"></param> internal static void HandleCreditRequest(NancyBlackDatabase db, SaleOrder saleorder) { if (saleorder.PaymentStatus != PaymentStatus.Credit) { return; } // only create one receivable per sale order var existingReceivable = db.Query <AccountingEntry>().Where(e => e.SaleOrderId == saleorder.Id && e.IncreaseAccount == "Receivable").FirstOrDefault(); if (existingReceivable != null) { // update amount if changed if (existingReceivable.IncreaseAmount != saleorder.TotalAmount) { existingReceivable.IncreaseAmount = saleorder.TotalAmount; db.UpsertRecord(existingReceivable); } return; } AccountingEntry receivableEntry = new AccountingEntry(); receivableEntry.TransactionDate = DateTime.Now; receivableEntry.DueDate = DateTime.Now.Date.AddDays(30); receivableEntry.TransactionType = "newaccount"; receivableEntry.DebtorLoanerName = "Receivable From Sales"; receivableEntry.IncreaseAccount = "Receivable"; receivableEntry.IncreaseAmount = saleorder.TotalAmount; receivableEntry.SaleOrderId = saleorder.Id; db.UpsertRecord(receivableEntry); }
public async Task <IActionResult> Edit(int id, AccountingEntry accountingEntry) { if (id != accountingEntry.ID) { return(NotFound()); } if (ModelState.IsValid) { try { _context.Update(accountingEntry); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!AccountingEntryExists(accountingEntry.ID)) { return(NotFound()); } else { throw; } } return(RedirectToAction("Index")); } return(View(accountingEntry)); }
public async Task <IActionResult> Create(AccountingEntry accountingEntry) { accountingEntry.MoneyCurrencyRate = (from c in _context.MoneyCurrency where c.ID.ToString() == accountingEntry.MoneyCurrency.ToString() select c.LastExchangeRate).Single(); accountingEntry.AccountToDebitDescription = (from c in _context.AccountingAccount where c.ID.ToString() == accountingEntry.AccountToDebit.ToString() select c.Description).Single(); accountingEntry.AccountToCreditDescription = (from c in _context.AccountingAccount where c.ID.ToString() == accountingEntry.AccountToCredit.ToString() select c.Description).Single(); accountingEntry.IsMajorizationProcessed = MajorizationProcessed.NotProcessed; if (ModelState.IsValid) { _context.Add(accountingEntry); await _context.SaveChangesAsync(); return(RedirectToAction("Index")); } return(View(accountingEntry)); }
/// <summary> /// Automatically create recurrance /// </summary> /// <param name="db"></param> /// <param name="entry"></param> internal static void ProcesAutoRecurranceCreation(NancyBlackDatabase db, AccountingEntry entry) { if (entry.Addendum == null) { return; } if (entry.Addendum.Recurring == true) { var lastPayment = (DateTime)entry.Addendum.LastPayment; var entries = new List <AccountingEntry>(); var start = entry.DueDate; var index = 2; while (start.AddMonths(1) <= lastPayment) { start = start.AddMonths(1); var copy = JObject.FromObject(entry).ToObject <AccountingEntry>(); copy.TransactionDate = start; copy.DueDate = start; copy.Id = 0; copy.Notes = "Recurring " + index + " of Entry:" + entry.Id + "\r\n" + entry.Notes; copy.Addendum.RecurringMaster = entry.Id; entries.Add(copy); index++; } db.Connection.InsertAll(entries); } }
public IOperationResult <AccountingEntry> FindAccountingEntry(long accountingEntryId) { AccountingEntry accountingEntry = _accountEntryRepository.Find(currency => currency.Id == accountingEntryId); return(accountingEntry != null ? BasicOperationResult <AccountingEntry> .Ok(accountingEntry) : BasicOperationResult <AccountingEntry> .Fail("NotFound")); }
public IActionResult UpdateCurrency(AccountingEntry request) { IOperationResult <AccountingEntry> operationResult = _accountingEntriesManager.UpdateAccounting(request); return(operationResult.Success ? Ok(operationResult.Entity) : (IActionResult)BadRequest(operationResult.Message)); }
public void Creating_WithoutLineSumsBeingZero_ThrowsException() { var credit = new CreditBuilder().WithNetSum(100).WithVat(24).Build(); var debit = new DebitBuilder().WithNetSum(10).WithVat(10).Build(); var sut = new AccountingEntryBuilder().WithLine(credit).WithLine(debit); Assert.IsFalse(AccountingEntry.IsValid(new AccountingEntryLine[] { credit, debit })); Assert.Throws <ArgumentException>(() => sut.Build()); }
public string Format(AccountingEntry entry) { var dtos = entry .GetLines() .Select(ToDto) .ToList(); var csvBytes = ToCsv(dtos); return(Encoding.UTF8.GetString(csvBytes)); }
internal static void ProcessReceiptCreation(NancyBlackDatabase db, Receipt obj) { // When payment receipt is created, create accounting entry db.Transaction(() => { var saleorder = db.GetById <SaleOrder>(obj.SaleOrderId); var paymentlog = db.GetById <PaymentLog>(obj.PaymentLogId); if (saleorder == null || paymentlog == null) { // bogus receipt throw new InvalidOperationException("Invalid Receipt was created"); } // Ensures all sale order logic has been ran // if the sale order was created before new system change if (saleorder.__createdAt < TaxSystemEpoch) { saleorder.UpdateSaleOrder(AdminModule.ReadSiteSettings(), db, false); } // Receipt will create 2 entries // 1) PaymentSource account increases, with total amount // TODO: Mapping from PaymentSource to Account AccountingEntry entry1 = new AccountingEntry(); entry1.TransactionDate = paymentlog.__createdAt; entry1.TransactionType = "income"; entry1.DebtorLoanerName = "Customer"; entry1.IncreaseAccount = paymentlog.PaymentSource; entry1.IncreaseAmount = saleorder.TotalAmount; entry1.SaleOrderId = saleorder.Id; db.UpsertRecord(entry1); if (saleorder.TotalTax > 0) { // 2) paid tax is decreased // (ภาษีขาย ทำให้ภาษีซื้อลดลง, ภาษีซื้อ บันทึกไว้ตอน InventoryInbound) AccountingEntry entry2 = new AccountingEntry(); entry2.TransactionDate = paymentlog.__createdAt; entry2.TransactionType = "expense"; entry2.DebtorLoanerName = "Tax"; entry2.DecreaseAccount = "Paid Tax"; entry2.DecreaseAmount = saleorder.TotalTax * -1; entry2.SaleOrderId = saleorder.Id; db.UpsertRecord(entry2); } }); }
public void SaveAccountingEntry(AccountingEntry accountingEntry) { using (DeepBlueEntities context = new DeepBlueEntities()) { if (accountingEntry.AccountingEntryID == 0) { context.AccountingEntries.AddObject(accountingEntry); } else { // Define an ObjectStateEntry and EntityKey for the current object. EntityKey key = default(EntityKey); object originalItem = null; key = context.CreateEntityKey("AccountingEntries", accountingEntry); // Get the original item based on the entity key from the context // or from the database. if (context.TryGetObjectByKey(key, out originalItem)) { // Call the ApplyCurrentValues method to apply changes // from the updated item to the original version. context.ApplyCurrentValues(key.EntitySetName, accountingEntry); } } context.SaveChanges(); } }
/// <summary> /// Submit purchase invoice and create neccessary accounting entries /// </summary> /// <param name="pi"></param> public static void SubmitPurchaseInvoice(PurchaseInvoice pi, NancyBlackDatabase db) { List <AccountingEntry> toAdd = new List <AccountingEntry>(); var inventoryEntry = new AccountingEntry(); inventoryEntry.TransactionDate = pi.PurchasedDate; inventoryEntry.IncreaseAccount = "Inventory"; inventoryEntry.IncreaseAmount = pi.TotalProductValue; inventoryEntry.DecreaseAccount = pi.PaidByAccount; inventoryEntry.DecreaseAmount = pi.TotalProductValue * -1; inventoryEntry.DocumentNumber = pi.SupplierInvoiceNumber; inventoryEntry.DebtorLoanerName = db.GetById <Supplier>(pi.SupplierId).Name; inventoryEntry.Notes = ""; foreach (var item in pi.Items) { inventoryEntry.Notes += item.Qty + "x" + db.GetById <Product>(item.ProductId).Title + "\r\n"; } toAdd.Add(inventoryEntry); var taxCredit = new AccountingEntry(); taxCredit.TransactionDate = pi.PurchasedDate; taxCredit.IncreaseAccount = "Tax Credit"; taxCredit.IncreaseAmount = pi.Tax; taxCredit.DecreaseAccount = pi.PaidByAccount; taxCredit.DecreaseAmount = pi.Tax * -1; taxCredit.DocumentNumber = pi.SupplierInvoiceNumber; taxCredit.DebtorLoanerName = "Tax"; taxCredit.Notes = "Tax Credit from Invoice: " + pi.SupplierInvoiceNumber + ", " + inventoryEntry.DebtorLoanerName; toAdd.Add(taxCredit); if (pi.AdditionalCost != 0) { var addCost = new AccountingEntry(); addCost.TransactionDate = pi.PurchasedDate; addCost.IncreaseAccount = "Expense"; addCost.IncreaseAmount = pi.AdditionalCost; addCost.DecreaseAccount = pi.PaidByAccount; addCost.DecreaseAmount = pi.AdditionalCost * -1; addCost.DocumentNumber = pi.SupplierInvoiceNumber; addCost.DebtorLoanerName = inventoryEntry.DebtorLoanerName; addCost.Notes = "Additional cost of buying from: " + pi.SupplierInvoiceNumber; toAdd.Add(addCost); } if (pi.Shipping != 0) { var shipping = new AccountingEntry(); shipping.TransactionDate = pi.PurchasedDate; shipping.IncreaseAccount = "Expense"; shipping.IncreaseAmount = pi.Shipping; shipping.DecreaseAccount = pi.PaidByAccount; shipping.DecreaseAmount = pi.Shipping * -1; shipping.DocumentNumber = pi.SupplierInvoiceNumber; shipping.DebtorLoanerName = inventoryEntry.DebtorLoanerName; shipping.Notes = "Shipping cost of buying from: " + pi.SupplierInvoiceNumber; if (!string.IsNullOrEmpty(pi.ShippingInvoiceNumber)) { shipping.DocumentNumber = pi.ShippingInvoiceNumber; } toAdd.Add(shipping); } foreach (var item in toAdd) { item.__createdAt = DateTime.Now; item.__updatedAt = DateTime.Now; } if (pi.IsConsignment) { inventoryEntry.DecreaseAccount = "Payable"; inventoryEntry.DueDate = pi.ConsignmentDueDate; if (pi.TaxEffectiveDate == default(DateTime)) { toAdd.Remove(taxCredit); } else { taxCredit.TransactionDate = pi.TaxEffectiveDate; } } db.Connection.InsertAll(toAdd); }
internal static void ProcessReceiptCreation(NancyBlackDatabase db, Receipt obj) { // When payment receipt is created, create accounting entry db.Transaction(() => { var saleorder = db.GetById <SaleOrder>(obj.SaleOrderId); var paymentlog = db.GetById <PaymentLog>(obj.PaymentLogId); if (paymentlog.Amount <= 0) { return; // perhaps it is an error } if (saleorder == null || paymentlog == null) { // bogus receipt throw new InvalidOperationException("Invalid Receipt was created"); } var currentSite = saleorder.SiteSettings; if (currentSite == null) { currentSite = AdminModule.ReadSiteSettings(); } // Ensures all sale order logic has been ran // if the sale order was created before new system change if (saleorder.__createdAt < TaxSystemEpoch) { saleorder.UpdateSaleOrder(currentSite, db, false); } // Receipt will create 4 entries // 1) PaymentSource account increases, with amount paid // TODO: Mapping from PaymentSource to Account AccountingEntry entry1 = new AccountingEntry(); entry1.TransactionDate = paymentlog.__createdAt; entry1.TransactionType = "income"; entry1.DebtorLoanerName = "Customer"; entry1.IncreaseAccount = paymentlog.PaymentSource; entry1.IncreaseAmount = paymentlog.Amount; entry1.SaleOrderId = saleorder.Id; db.UpsertRecord(entry1); // 2) Sales Tax Calculation { AccountingEntry taxExtry = new AccountingEntry(); taxExtry.TransactionDate = paymentlog.__createdAt; taxExtry.TransactionType = "taxcredit"; taxExtry.DebtorLoanerName = "Tax"; taxExtry.DecreaseAccount = "Tax Credit"; taxExtry.SaleOrderId = saleorder.Id; if (currentSite.commerce.billing.vattype == "addvat") { var tax = paymentlog.Amount * ((100 + (Decimal)currentSite.commerce.billing.vatpercent) / 100); taxExtry.DecreaseAmount = tax * -1; } if (currentSite.commerce.billing.vattype == "includevat") { var tax = paymentlog.Amount * ((Decimal)currentSite.commerce.billing.vatpercent / 100); taxExtry.DecreaseAmount = tax * -1; } db.UpsertRecord(taxExtry); } // 3) Payment Fee if (paymentlog.Fee > 0) { AccountingEntry feeEntry = new AccountingEntry(); feeEntry.TransactionDate = paymentlog.__createdAt; feeEntry.TransactionType = "buy"; feeEntry.DebtorLoanerName = paymentlog.PaymentSource; feeEntry.IncreaseAccount = "Payment Fee - " + paymentlog.PaymentSource; feeEntry.IncreaseAmount = paymentlog.Fee; feeEntry.SaleOrderId = saleorder.Id; db.UpsertRecord(feeEntry); } // 4) Receivable from the Sale Order { // existing receivable of this sale order var existingReceivable = db.Query <AccountingEntry>().Where(e => e.SaleOrderId == saleorder.Id && e.IncreaseAccount == "Receivable").ToList(); // see if we have any receivable of this sale order // if we had, we have to deduct it if (existingReceivable.Count > 0) { AccountingEntry deductReceivableEntry = new AccountingEntry(); deductReceivableEntry.TransactionDate = paymentlog.__createdAt; deductReceivableEntry.TransactionType = "arpayment"; deductReceivableEntry.DebtorLoanerName = "Receivable From Sales"; deductReceivableEntry.DecreaseAccount = "Receivable"; deductReceivableEntry.DecreaseAmount = paymentlog.Amount; deductReceivableEntry.SaleOrderId = saleorder.Id; db.UpsertRecord(deductReceivableEntry); } else { // this maybe the first payment, see if all amount has been paid // see all payment log of this sale order // we only query payments up to currently processing payment log // so that when we re var payments = db.Query <PaymentLog>().Where(l => l.SaleOrderId == saleorder.Id && l.Id <= paymentlog.Id).ToList(); var remaining = saleorder.TotalAmount - payments.Sum(p => p.Amount); if (remaining > 0) { // this is partial payment - create new receivable AccountingEntry receivableEntry = new AccountingEntry(); receivableEntry.TransactionDate = paymentlog.__createdAt; receivableEntry.TransactionType = "newaccount"; receivableEntry.DebtorLoanerName = "Receivable From Sales"; receivableEntry.IncreaseAccount = "Receivable"; receivableEntry.IncreaseAmount = remaining; receivableEntry.SaleOrderId = saleorder.Id; db.UpsertRecord(receivableEntry); } // this is full payment in one go, no need for receivable } } }); }
public IEnumerable<ErrorInfo> SaveAccountingEntry(AccountingEntry accountingEntry) { return accountingEntry.Save(); }
internal static void ProcessInboundCompleted(NancyBlackDatabase db, InventoryInbound inbound, List <InventoryItem> items) { // this already in transaction // When inventory inbound is created, record into GL about current asset { var supplierLookup = db.Query <Supplier>().ToDictionary(s => s.Id); // Inbound will create 2 entries // 1) inventory increase and account decrease (without tax amount) AccountingEntry entry1 = new AccountingEntry(); entry1.TransactionDate = inbound.PaymentDate; entry1.TransactionType = "buy"; entry1.DebtorLoanerName = supplierLookup[inbound.SupplierId].Name; entry1.IncreaseAccount = "Inventory"; entry1.IncreaseAmount = inbound.TotalAmountWithoutTax; entry1.DecreaseAccount = inbound.PaymentAccount; entry1.DecreaseAmount = inbound.TotalAmountWithoutTax * -1; entry1.InventoryInboundId = inbound.Id; db.UpsertRecord(entry1); // 2) paid tax increase and account decrease (tax only amount) // (ภาษีซื้อทำให้ภาษีขายที่ต้องจ่ายลดลง) if (inbound.TotalTax > 0) { AccountingEntry entry2 = new AccountingEntry(); entry2.TransactionDate = inbound.PaymentDate; entry2.TransactionType = "expense"; entry2.DebtorLoanerName = "Tax"; entry2.IncreaseAccount = "Paid Tax"; entry2.IncreaseAmount = inbound.TotalTax; entry2.DecreaseAccount = inbound.PaymentAccount; entry2.DecreaseAmount = inbound.TotalTax * -1; entry2.InventoryInboundId = inbound.Id; db.UpsertRecord(entry2); } } // record that inventory was withdrawn { var allFullfilled = from item in items where item.IsFullfilled == true select item; if (allFullfilled.Count() > 0) { // the inventory is withdrawn as expense AccountingEntry entry1 = new AccountingEntry(); entry1.TransactionDate = inbound.PaymentDate; entry1.TransactionType = "expense"; entry1.DebtorLoanerName = "Inventory Used"; entry1.DecreaseAccount = "Inventory"; entry1.DecreaseAmount = allFullfilled.Sum(item => item.BuyingCost) * -1; entry1.Notes = "Inventory Used by Sale Order: " + string.Join(",", allFullfilled.Select(item => item.SaleOrderId)) + "From Inbound Id:" + inbound.Id; db.UpsertRecord(entry1); // if there is net profit/loss - record it // but does not remove the amount from account var totalAmountBuy = allFullfilled.Sum(i => i.BuyingCost); var totalAmountSold = allFullfilled.Sum(i => i.SellingPrice); if (totalAmountBuy != totalAmountSold) { AccountingEntry entry2 = new AccountingEntry(); entry2.TransactionDate = inbound.PaymentDate; entry2.TransactionType = "income"; entry2.DebtorLoanerName = "n/a"; entry2.IncreaseAccount = "Gross Profit"; entry2.IncreaseAmount = totalAmountSold - totalAmountBuy; entry2.Notes = "From Inbound Id:" + inbound.Id + " the item were used. Profit/Loss is calculated and recorded into Profit(Loss) account for each account"; db.UpsertRecord(entry2); } } } }
public void CreateAccountingEntry(DeepBlue.Models.Accounting.Enums.AccountingTransactionType accountingTransactionType, int fundID, int entityID, IAccountable accountableItem, decimal? amount = null, int? accountingTransactionSubTypeID = null) { DeepBlueEntities context = new DeepBlueEntities(); decimal amt = amount.HasValue ? amount.Value : (accountableItem.Amount.HasValue ? accountableItem.Amount.Value : 0); var query = from aet in context.AccountingEntryTemplates where aet.EntityID == entityID && aet.AccountingTransactionTypeID == (int)accountingTransactionType select aet; // See if there are any templates specific to the Fund List<AccountingEntryTemplate> templates = query.Where(x => x.FundID == fundID).ToList(); if (templates.Count <= 0) { // No templates found for this fund.. try to see if there is an Entity level template available templates = query.Where(x => x.FundID == null).ToList(); } if (templates.Count > 0) { // Filter on the sub type if (accountingTransactionSubTypeID.HasValue) { //var templatesWithSubType = templates.Where(x => x.AccountingTransactionSubTypeID == accountingTransactionSubTypeID.Value).ToList(); //if (templatesWithSubType.Count > 0) { // templates = templatesWithSubType; //} } List<AccountingEntry> accountingEntries = new List<AccountingEntry>(); foreach (AccountingEntryTemplate template in templates) { // each template will result in an accounting entry AccountingEntry entry = new AccountingEntry(); entry.AccountingEntryTemplateID = template.AccountingEntryTemplateID; DeepBlue.Models.Accounting.Enums.AccountingEntryAmountType amountType = (DeepBlue.Models.Accounting.Enums.AccountingEntryAmountType)template.AccountingEntryAmountTypeID; switch (amountType) { case DeepBlue.Models.Accounting.Enums.AccountingEntryAmountType.FixedAmount: entry.Amount = Convert.ToDecimal(template.AccountingEntryAmountTypeData); break; case DeepBlue.Models.Accounting.Enums.AccountingEntryAmountType.Percentage: decimal percent = Convert.ToDecimal(template.AccountingEntryAmountTypeData); entry.Amount = (percent * amt) / 100; break; case DeepBlue.Models.Accounting.Enums.AccountingEntryAmountType.Field: // Use reflection to get the amount PropertyInfo property = accountableItem.GetType().GetProperties().Where(x => x.Name == template.AccountingEntryAmountTypeData).FirstOrDefault(); object val = property.GetValue(accountableItem, null); if (val != null) { entry.Amount = Convert.ToDecimal(val); } break; case DeepBlue.Models.Accounting.Enums.AccountingEntryAmountType.Custom: break; default: entry.Amount = amt; break; } entry.TraceID = accountableItem.TraceID; entry.AttributedTo = accountableItem.AttributedTo; entry.AttributedToName = accountableItem.AttributedToName; entry.AttributedToType = accountableItem.AttributedToType; entry.FundID = fundID; entry.EntityID = entityID; context.AccountingEntries.AddObject(entry); context.SaveChanges(); } } }