/// <summary> /// Update a document after editing /// </summary> public AjaxReturn DocumentSave(BankingDocument json) { Database.BeginTransaction(); Extended_Document document = json.header; JObject oldDoc = getCompleteDocument(document.idDocument); DocType t = checkDocType(document.DocumentTypeId, DocType.Withdrawal, DocType.Deposit, DocType.CreditCardCharge, DocType.CreditCardCredit); FullAccount acct = Database.Get <FullAccount>((int)document.DocumentAccountId); checkAcctType(acct.AccountTypeId, AcctType.Bank, AcctType.CreditCard, AcctType.Investment, AcctType.OtherAsset, AcctType.OtherLiability); allocateDocumentIdentifier(document, acct); int sign = SignFor(t); Extended_Document original = getDocument(document); decimal vat = 0; decimal net = 0; bool lineVat = false; // Flag to indicate this is a withdrawal to pay the VAT to HMRC foreach (InvoiceLine detail in json.detail) { if (detail.AccountId == 0 || detail.AccountId == null) { Utils.Check(detail.LineAmount == 0 && detail.VatAmount == 0, "All lines must be allocated to an account"); continue; } net += detail.LineAmount; vat += detail.VatAmount; } Utils.Check(document.DocumentAmount == net + vat, "Document does not balance"); decimal changeInDocumentAmount = -sign * (document.DocumentAmount - original.DocumentAmount); int lineNum = 1; fixNameAddress(document, "O"); Database.Update(document); int nextDocid = Utils.ExtractNumber(document.DocumentIdentifier); if (nextDocid > 0 && acct.RegisterNumber(t, nextDocid)) { Database.Update(acct); } // Find any existing VAT record Journal vatJournal = Database.QueryOne <Journal>("SELECT * FROM Journal WHERE DocumentId = " + document.idDocument + " AND AccountId = " + (int)Acct.VATControl + " ORDER BY JournalNum DESC"); Journal journal = Database.Get(new Journal() { DocumentId = (int)document.idDocument, JournalNum = lineNum }); journal.DocumentId = (int)document.idDocument; journal.AccountId = document.DocumentAccountId; journal.NameAddressId = document.DocumentNameAddressId; journal.Memo = document.DocumentMemo; journal.JournalNum = lineNum++; journal.Amount += changeInDocumentAmount; journal.Outstanding += changeInDocumentAmount; Database.Update(journal); foreach (InvoiceLine detail in json.detail) { if (detail.AccountId == 0 || detail.AccountId == null) { continue; } Utils.Check(!lineVat, "Withdrawal to VAT account may only have 1 line"); if (detail.AccountId == (int)Acct.VATControl) { // This is a VAT payment to HMRC Utils.Check(lineNum == 2, "Withdrawal to VAT account may only have 1 line"); Utils.Check(vat == 0, "Withdrawal to VAT account may not have a VAT amount"); vat = detail.LineAmount; lineVat = true; } journal = Database.Get(new Journal() { DocumentId = (int)document.idDocument, JournalNum = lineNum }); journal.DocumentId = (int)document.idDocument; journal.JournalNum = lineNum++; journal.AccountId = (int)detail.AccountId; journal.NameAddressId = document.DocumentNameAddressId; journal.Memo = detail.Memo; journal.Amount = sign * detail.LineAmount; journal.Outstanding = sign * detail.LineAmount; Database.Update(journal); Line line = new Line() { idLine = journal.idJournal, Qty = 0, LineAmount = detail.LineAmount, VatCodeId = detail.VatCodeId, VatRate = detail.VatRate, VatAmount = detail.VatAmount }; Database.Update(line); } Database.Execute("DELETE FROM Line WHERE idLine IN (SELECT idJournal FROM Journal WHERE DocumentId = " + document.idDocument + " AND JournalNum >= " + lineNum + ")"); Database.Execute("DELETE FROM Journal WHERE DocumentId = " + document.idDocument + " AND JournalNum >= " + lineNum); if (vat != 0 || vatJournal.idJournal != null) { // Add the VAT journal at the end vat *= sign; decimal changeInVatAmount = vat - vatJournal.Amount; Utils.Check(document.VatPaid == null || document.VatPaid < 1 || changeInVatAmount == 0, "Cannot alter VAT on this document, it has already been declared"); if (!lineVat) { vatJournal.DocumentId = (int)document.idDocument; vatJournal.AccountId = (int)Acct.VATControl; vatJournal.NameAddressId = document.DocumentNameAddressId; vatJournal.Memo = "Total VAT"; vatJournal.JournalNum = lineNum++; vatJournal.Amount = vat; vatJournal.Outstanding += changeInVatAmount; Database.Update(vatJournal); } } JObject newDoc = getCompleteDocument(document.idDocument); Database.AuditUpdate("Document", document.idDocument, oldDoc, newDoc); Settings.RegisterNumber(this, document.DocumentTypeId, Utils.ExtractNumber(document.DocumentIdentifier)); Database.Commit(); return(new AjaxReturn() { message = "Document saved", id = document.idDocument }); }