} // End of the AddOrder method /// <summary> /// Add an supplier invoice /// </summary> public async Task<SupplierInvoiceRoot> AddSupplierInvoice(string dox_email, AnnytabDoxTrade doc) { // Terms of payment if (string.IsNullOrEmpty(doc.terms_of_payment) == false) { doc.terms_of_payment = CommonTools.ConvertToAlphanumeric(doc.terms_of_payment).ToUpper().Replace("-", ""); await AddTermsOfPayment(doc.terms_of_payment); } // Currency if (string.IsNullOrEmpty(doc.currency_code) == false) { doc.currency_code = doc.currency_code.ToUpper(); await AddCurrency(doc.currency_code); } // Upsert the supplier SupplierRoot supplier_root = await UpsertSupplier(dox_email, doc); // Return if the supplier_root is null if(supplier_root == null || supplier_root.Supplier == null) { return null; } // Create a list with supplier invoice rows IList<SupplierInvoiceRow> rows = new List<SupplierInvoiceRow>(); //// Add accounts payable amount //if(doc.total != null && doc.total != 0M) //{ // rows.Add(new SupplierInvoiceRow // { // Code = "TOT", // Total = doc.total * -1 // }); //} //// Add value added tax //if (doc.vat_total != null && doc.vat_total != 0M) //{ // rows.Add(new SupplierInvoiceRow // { // Code = "VAT", // Total = doc.vat_total // }); //} //// Add rounding //if(doc.rounding != null && doc.rounding != 0M) //{ // rows.Add(new SupplierInvoiceRow // { // Code = "ROV", // Total = doc.rounding // }); //} // Add supplier invoice rows if (doc.product_rows != null) { await AddSupplierInvoiceRows(doc.product_rows, rows); } // Create a supplier invoice SupplierInvoiceRoot root = new SupplierInvoiceRoot { SupplierInvoice = new SupplierInvoice { SupplierNumber = supplier_root.Supplier.SupplierNumber, InvoiceNumber = string.IsNullOrEmpty(doc.payment_reference) == false ? doc.payment_reference : null, InvoiceDate = string.IsNullOrEmpty(doc.issue_date) == false ? doc.issue_date : null, DueDate = string.IsNullOrEmpty(doc.due_date) == false ? doc.due_date : null, Currency = doc.currency_code, Comments = doc.comment, Total = doc.total != null ? doc.total : 0M, VAT = doc.vat_total != null ? doc.vat_total : 0M, RoundOffValue = doc.rounding != null ? doc.rounding : 0M, SupplierInvoiceRows = rows } }; // Add a supplier invoice FortnoxResponse<SupplierInvoiceRoot> fr = await this.nox_client.Add<SupplierInvoiceRoot>(root, "supplierinvoices"); // Log errors if (string.IsNullOrEmpty(fr.error) == false) { this.logger.LogError(fr.error); } // Return the supplier invoice return fr.model; } // End of the AddSupplierInvoice method
public async Task TestAddPost() { // Create a post //SupplierInvoiceRoot post = new SupplierInvoiceRoot //{ // SupplierInvoice = new SupplierInvoice // { // SupplierNumber = "502", // InvoiceNumber = "D46", // InvoiceDate = "2019-08-06", // DueDate = "2019-08-21", // Currency = "SEK", // Total = 203M, // VAT = 40.625M, // RoundOffValue = -0.125M, // VATType = "NORMAL", // //SalesType = "STOCK", //Ett fel uppstod i lagermodulen (2003127) // SupplierInvoiceRows = new List<SupplierInvoiceRow> // { // new SupplierInvoiceRow // { // ArticleNumber = "GiB", // Account = "6210", // ItemDescription = "Gibibytes", // Quantity = 10, // Price = 8 // }, // new SupplierInvoiceRow // { // ArticleNumber = "File", // Account = "6210", // ItemDescription = "Filer", // Quantity = 33, // Price = 2.50M // } // } // } //}; SupplierInvoiceRoot post = new SupplierInvoiceRoot { SupplierInvoice = new SupplierInvoice { SupplierNumber = "502", InvoiceNumber = "D46", InvoiceDate = "2019-08-06", DueDate = "2019-08-21", Currency = "SEK", Total = -203M, VAT = -40.625M, RoundOffValue = 0.125M, VATType = "NORMAL", //SalesType = "STOCK", //Ett fel uppstod i lagermodulen (2003127) SupplierInvoiceRows = new List<SupplierInvoiceRow> { new SupplierInvoiceRow { ArticleNumber = "GiB", Account = "6210", ItemDescription = "Gibibytes", Quantity = -10, Price = 8 }, new SupplierInvoiceRow { ArticleNumber = "File", Account = "6210", ItemDescription = "Filer", Quantity = -33, Price = 2.50M } } } }; // Add the post FortnoxResponse<SupplierInvoiceRoot> fr = await config.fortnox_client.Add<SupplierInvoiceRoot>(post, "supplierinvoices"); // Log the error if (fr.model == null) { config.logger.LogError(fr.error); } // Test evaluation Assert.AreNotEqual(null, fr.model); } // End of the TestAddPost method
} // End of the run method /// <summary> /// Import to Fortnox /// </summary> private async Task RunImport(string directory, IDoxservrFilesClient dox_files_client, IFortnoxClient nox_client) { // Log the start this.logger.LogInformation("START: Importing documents to Fortnox!"); // Get files from doxservr await GetDoxservrFiles(directory); // Create a list with accounts IList<string> accounts = new List<string> { this.default_values.SalesAccountEUREVERSEDVAT, this.default_values.SalesAccountEUVAT, this.default_values.SalesAccountEXPORT, this.default_values.SalesAccountSE0, this.default_values.SalesAccountSE12, this.default_values.SalesAccountSE25, this.default_values.SalesAccountSE6, this.default_values.SalesAccountSEREVERSEDVAT, this.default_values.PurchaseAccount }; // Add accounts foreach(string account in accounts) { if(string.IsNullOrEmpty(account) == false) { await this.fortnox_importer.AddAccount(account); } } // Add a price list if (string.IsNullOrEmpty(this.default_values.PriceList) == false) { this.default_values.PriceList = this.default_values.PriceList.ToUpper(); await this.fortnox_importer.AddPriceList(this.default_values.PriceList); } // Upsert currency rates //DoxservrResponse<FixerRates> dr_fixer_rates = await this.fixer_client.UpdateCurrencyRates(directory); //if(dr_fixer_rates.model != null) //{ // await this.fortnox_importer.UpsertCurrencies(dr_fixer_rates.model); //} // Get email senders EmailSendersRoot email_senders = null; if(this.default_values.OnlyAllowTrustedSenders == true) { email_senders = await this.fortnox_importer.GetTrustedEmailSenders(); } // Get downloaded metadata files string[] metadata_files = System.IO.Directory.GetFiles(directory + "\\Files\\Meta\\"); // Loop metadata files foreach(string meta_path in metadata_files) { // Metadata FileDocument post = null; try { // Get the meta data string meta_data = System.IO.File.ReadAllText(meta_path, Encoding.UTF8); // Make sure that there is meta data if (string.IsNullOrEmpty(meta_data) == true) { this.logger.LogError($"File is empty: {meta_path}"); continue; } // Get the post post = JsonConvert.DeserializeObject<FileDocument>(meta_data); } catch (Exception ex) { // Log the error this.logger.LogError(ex, $"Deserialize file: {meta_path}", null); continue; } // Make sure that the post not is null if(post == null) { // Log the error this.logger.LogError($"Post is null: {meta_path}", null); continue; } // Get the sender Party sender = null; foreach (Party party in post.parties) { if (party.is_sender == 1) { sender = party; break; } } // Check if we only should allow trusted senders if(this.default_values.OnlyAllowTrustedSenders == true) { // Check if the sender is a trusted sender bool trusted = false; foreach(EmailSender email_sender in email_senders.EmailSenders.TrustedSenders) { if(email_sender.Email == sender.email) { trusted = true; break; } } // Check if the sender is trusted if(trusted == false) { // Log the error this.logger.LogError($"{sender.email} is not trusted, add the email to the list of trusted email addresses in Fortnox (Inställningar/Arkivplats)."); continue; } } // Get the file path string file_path = directory + "\\Files\\" + post.id + CommonTools.GetExtensions(post.filename); // Make sure that the file exists if(System.IO.File.Exists(file_path) == false) { // Log the error this.logger.LogError($"File not found: {file_path}."); continue; } // Document AnnytabDoxTrade doc = null; try { // Get file data string file_data = System.IO.File.ReadAllText(file_path, CommonTools.GetEncoding(post.file_encoding, Encoding.UTF8)); // Make sure that there is file data if(string.IsNullOrEmpty(file_data) == true) { // Log the error this.logger.LogError($"File is empty: {file_path}."); continue; } // Get the document doc = JsonConvert.DeserializeObject<AnnytabDoxTrade>(file_data); } catch(Exception ex) { // Log the error this.logger.LogError(ex, $"Deserialize file: {file_path}", null); continue; } // Make sure that the document not is null if (doc == null) { // Log the error this.logger.LogError($"Post is null: {file_path}", null); continue; } // Create an error variable bool error = false; // Check the document type if (doc.document_type == "request_for_quotation") { // Log information this.logger.LogInformation($"Starts to import offer {post.id}.json to Fortnox."); // Import as offer OfferRoot offer_root = await this.fortnox_importer.AddOffer(sender.email, doc); if (offer_root == null) { // Log the error error = true; this.logger.LogError($"Offer, {post.id}.json was not imported to Fortnox."); } else { // Log information this.logger.LogInformation($"Offer, {post.id}.json was imported to Fortnox."); } } else if (doc.document_type == "quotation") { // Log information this.logger.LogInformation($"Quotation {post.id}.json is not imported to Fortnox."); } else if (doc.document_type == "order") { // Log information this.logger.LogInformation($"Starts to import order {post.id}.json to Fortnox."); // Import as order OrderRoot order_root = await this.fortnox_importer.AddOrder(sender.email, doc); if (order_root == null) { // Log the error error = true; this.logger.LogError($"Order, {post.id}.json was not imported to Fortnox."); } else { // Log information this.logger.LogInformation($"Order, {post.id}.json was imported to Fortnox."); } } else if (doc.document_type == "order_confirmation") { // Log information this.logger.LogInformation($"Order confirmation {post.id}.json is not imported to Fortnox."); } else if (doc.document_type == "invoice") { // Log information this.logger.LogInformation($"Starts to import supplier invoice {post.id}.json to Fortnox."); // Import as supplier invoice SupplierInvoiceRoot invoice_root = await this.fortnox_importer.AddSupplierInvoice(sender.email, doc); if (invoice_root == null) { // Log the error error = true; this.logger.LogError($"Supplier invoice, {post.id}.json was not imported to Fortnox."); } else { // Log information this.logger.LogInformation($"Supplier invoice, {post.id}.json was imported to Fortnox."); } } else if (doc.document_type == "credit_invoice") { // Log information this.logger.LogInformation($"Starts to import supplier credit invoice {post.id}.json to Fortnox."); // Import as supplier credit invoice SupplierInvoiceRoot invoice_root = await this.fortnox_importer.AddSupplierInvoice(sender.email, doc); if (invoice_root == null) { // Log the error error = true; this.logger.LogError($"Supplier credit invoice, {post.id}.json was not imported to Fortnox."); } else { // Log information this.logger.LogInformation($"Supplier credit invoice, {post.id}.json was imported to Fortnox."); } } // Move files if no error was encountered if(error == false) { // Create destination paths string meta_destination = directory + $"\\Files\\Meta\\Imported\\{post.id}.json"; string file_destination = directory + $"\\Files\\Imported\\{post.id}.json"; try { // Delete destination files if the exists if(System.IO.File.Exists(meta_destination) == true) { System.IO.File.Delete(meta_destination); } if(System.IO.File.Exists(file_destination) == true) { System.IO.File.Delete(file_destination); } // Move files System.IO.Directory.Move(meta_path, meta_destination); System.IO.Directory.Move(file_path, file_destination); } catch (Exception ex) { // Log the exception this.logger.LogError(ex, "Moving files", null); } } } // Log the end this.logger.LogInformation("END: Importing documents to Fortnox!"); } // End of the RunImport method
public async Task TestUpdatePost() { // Create a post SupplierInvoiceRoot post = new SupplierInvoiceRoot { SupplierInvoice = new SupplierInvoice { SupplierNumber = "1", InvoiceDate = "2017-11-01", DueDate = "2017-11-25", Total = 10000, VAT = 2000, VATType = "NORMAL", //SalesType = "STOCK", // Ett fel uppstod i lagermodulen (2003127) Currency = "SEK", CurrencyRate = 1, CurrencyUnit = 1, SupplierInvoiceRows = new List<SupplierInvoiceRow> { new SupplierInvoiceRow { Account = "2440", Code = "TOT", AccountDescription = "Leverantörsskulder", Debit = 0, Credit = 10000, Total = -10000 }, new SupplierInvoiceRow { Account = "2641", Code = "VAT", AccountDescription = "Ingående moms", Debit = 2000, Credit = 0, Total = 2000 }, new SupplierInvoiceRow { Account = "6250", Code = "PRE", AccountDescription = "Porto", Debit = 8000, Credit = 0, Total = 8000, ArticleNumber = "1", Quantity = 1000, Price = 8 } } } }; // Update the post FortnoxResponse<SupplierInvoiceRoot> fr = await config.fortnox_client.Update<SupplierInvoiceRoot>(post, "supplierinvoices/50"); // Log the error if (fr.model == null) { config.logger.LogError(fr.error); } // Test evaluation Assert.AreNotEqual(null, fr.model); } // End of the TestUpdatePost method