Exemplo n.º 1
0
 /// <summary>
 /// Post a matched transaction.
 /// May be called direct from StatementMatch for Same transactions,
 /// or when the user presses "Save" for other transactions
 /// </summary>
 public AjaxReturn StatementMatchPost(JObject json)
 {
     Utils.Check(SessionData.StatementMatch != null, "Invalid call to StatementMatchPost");
     MatchInfo match = SessionData.StatementMatch.ToObject<MatchInfo>();
     JArray transactions = SessionData.StatementImport.transactions;
     dynamic transaction = match.transaction < 0 ? null : SessionData.StatementImport.transactions[match.transaction];
     DocType type = match.transaction < 0 ? match.type == "Transfer" ? DocType.Transfer : DocType.Cheque :
         (DocType)((JObject)transactions[match.transaction]).AsInt("DocumentTypeId");
     AjaxReturn result;
     switch (type) {
         case DocType.Payment:
             result = new Customer() {
                 Context = Context,
                 GetParameters = GetParameters,
                 PostParameters = PostParameters,
                 Parameters = Parameters,
             }.PaymentPost(json.To<CustomerSupplier.PaymentDocument>());
             break;
         case DocType.BillPayment:
             result = new Supplier() {
                 Context = Context,
                 GetParameters = GetParameters,
                 PostParameters = PostParameters,
                 Parameters = Parameters,
             }.PaymentPost(json.To<CustomerSupplier.PaymentDocument>());
             break;
         case DocType.Cheque:
         case DocType.Deposit:
         case DocType.CreditCardCharge:
         case DocType.CreditCardCredit:
             result = DocumentPost(json.To<BankingDocument>());
             break;
         case DocType.Transfer:
             result = TransferPost(json.To<TransferDocument>());
             break;
         default:
             throw new CheckException("Unexpected document type:{0}", type.UnCamel());
     }
     if (result.error == null) {
         if(match.transaction >= 0 && match.type == "Same")
             transaction.Matched = 1;
         JArray items = SessionData.StatementImport.import;
         items.RemoveAt(match.current);
         result.redirect = "/banking/" + (items.Count == 0 ? "detail" : "statementmatching") + ".html?id=" + match.id;
     }
     return result;
 }
Exemplo n.º 2
0
 /// <summary>
 /// Update a matched transaction
 /// </summary>
 public void StatementMatch()
 {
     Utils.Check(SessionData.StatementMatch != null, "Invalid call to StatementMatch");
     MatchInfo match = SessionData.StatementMatch.ToObject<MatchInfo>();
     Account account = Database.Get<Account>(match.id);
     // The existing transaction to match (or empty record if none)
     Extended_Document transaction = match.transaction < 0 ? Database.EmptyRecord<Extended_Document>() :
         SessionData.StatementImport.transactions[match.transaction].ToObject<Extended_Document>();
     // The statement transaction
     dynamic current = SessionData.StatementImport.import[match.current];
     Utils.Check(current != null, "No current transaction");
     bool same = match.type == "Same";
     bool documentHasVat = false;
     bool payment = false;
     decimal cAmount = current.Amount;
     int id = transaction.idDocument ?? 0;
     DocType type = match.transaction < 0 ?
         match.type == "Transfer" ?
             DocType.Transfer :		// They specified a new transfer
             cAmount < 0 ?			// They specified a new transaction - type depends on sign and account type
                 account.AccountTypeId == (int)AcctType.Bank ?
                     DocType.Cheque : DocType.CreditCardCharge :
                 account.AccountTypeId == (int)AcctType.Bank ?
                     DocType.Deposit : DocType.CreditCardCredit :
         (DocType)transaction.DocumentTypeId;
     GetParameters["acct"] = match.id.ToString();	// This bank account
     // Call appropriate method to get Record, and therefore transaction
     // Also set Module and Method, so appropriate template is used to display transaction before posting
     switch (type) {
         case DocType.Payment:
             Module = "customer";
             Method = "payment";
             Customer cust = new Customer();
             cust.Payment(id);
             this.Record = cust.Record;
             payment = true;
             break;
         case DocType.BillPayment:
             Module = "supplier";
             Method = "payment";
             Supplier supp = new Supplier();
             supp.Payment(id);
             this.Record = supp.Record;
             payment = true;
             break;
         case DocType.Cheque:
         case DocType.Deposit:
         case DocType.CreditCardCharge:
         case DocType.CreditCardCredit:
             Method = "document";
             Document(id, type);
             documentHasVat = true;
             break;
         case DocType.Transfer:
             Method = "transfer";
             Transfer(id);
             break;
         default:
             throw new CheckException("Unexpected document type:{0}", type.UnCamel());
     }
     dynamic record = (JObject)Record;
     dynamic doc = record.header;
     if (id == 0 && type == DocType.Transfer && cAmount > 0) {
         // New transfer in
         doc.TransferAccountId = match.id;
         doc.DocumentAccountId = 0;
         doc.DocumentAccountName = "";
     }
     if (string.IsNullOrWhiteSpace(doc.DocumentMemo.ToString())) {
         // Generate a memo
         string name = current.Name;
         string memo = current.Memo;
         if (string.IsNullOrWhiteSpace(memo))
             memo = name;
         else if (!memo.Contains(name))
             memo = name + " " + memo;
         doc.DocumentMemo = memo;
     }
     if (!same) {
         // They want to create a new document - try to guess the DocumentName
         string name = doc.DocumentName;
         string currentName = current.Name;
         currentName = currentName.Split('\n', '\t')[0];
         if (string.IsNullOrWhiteSpace(name) || (!payment && name.SimilarTo(currentName) < 0.5)) {
             doc.DocumentName = currentName;
             NameAddress n = new NameAddress() {
                 Type = "O",
                 Name = currentName
             };
             doc.DocumentNameAddressId = Database.Get(n).idNameAddress ?? 0;
         }
     }
     doc.DocumentDate = current.Date;
     decimal tAmount = doc.DocumentAmount;
     decimal diff = Math.Abs(cAmount) - Math.Abs(tAmount);
     doc.DocumentAmount += diff;
     if(same)
         Utils.Check(diff == 0, "Amounts must be the same");
     else {
         // New transaction
         doc.DocumentOutstanding = doc.DocumentAmount;
         doc.Clr = "";
         doc.idDocument = doc.Id = null;
         if (Utils.ExtractNumber(doc.DocumentIdentifier.ToString()) > 0)
             doc.DocumentIdentifier = "";
     }
     if(string.IsNullOrEmpty(doc.DocumentIdentifier.ToString())) {
         if (current.Id != null) {
             doc.DocumentIdentifier = current.Id;
         } else {
             int no = Utils.ExtractNumber(current.Name.ToString());
             if (no != 0)
                 doc.DocumentIdentifier = no.ToString();
         }
     }
     if (diff != 0 && documentHasVat) {
         // Adjust first line to account for difference
         if (record.detail.Count == 0)
             record.detail.Add(new InvoiceLine().ToJToken());
         dynamic line = record.detail[0];
         decimal val = line.LineAmount + line.VatAmount + diff;
         if (line.VatRate != 0) {
             line.VatAmount = Math.Round(val * line.VatRate / (100 + line.VatRate), 2);
             val -= line.VatAmount;
         }
         line.LineAmount = val;
     }
     if (payment && !same)
         removePayments(record);
     record.StatementAccount = match.id;
     if (same) {
         // Just post the new information
         if (type == DocType.Transfer)
             record = record.header;		// Transfer posts header alone
         AjaxReturn p = StatementMatchPost((JObject)record);
         if (p.error == null)
             Redirect(p.redirect);		// If no error, go on with matching
     }
 }