} // End of the AddOrderRows method

        /// <summary>
        /// Add supplier invoice rows recursively
        /// </summary>
        private async Task AddSupplierInvoiceRows(IList<ProductRow> product_rows, IList<SupplierInvoiceRow> supplier_invoice_rows)
        {
            // Loop product rows
            foreach (ProductRow row in product_rows)
            {
                // Unit
                if (string.IsNullOrEmpty(row.unit_code) == false)
                {
                    row.unit_code = CommonTools.ConvertToAlphanumeric(row.unit_code).ToLower();
                    await AddUnit(row.unit_code);
                }

                // Article, add if there is an identifier
                ArticleRoot article_root = null;
                if (string.IsNullOrEmpty(row.product_code) == false || string.IsNullOrEmpty(row.manufacturer_code) == false || string.IsNullOrEmpty(row.gtin) == false)
                {
                    article_root = await AddArticle(row);
                }

                // Add a supplier invoice row
                supplier_invoice_rows.Add(new SupplierInvoiceRow
                {
                    ArticleNumber = article_root != null ? article_root.Article.ArticleNumber : null,
                    Account = article_root == null ? this.default_values.PurchaseAccount : null,
                    ItemDescription = row.product_name,
                    Quantity = row.quantity,
                    Price = row.unit_price
                    //Unit = article_root != null ? article_root.Article.Unit : row.unit_code      
                });

                // Check if there is sub rows
                if (row.subrows != null && row.subrows.Count > 0)
                {
                    await AddSupplierInvoiceRows(row.subrows, supplier_invoice_rows);
                }
            }

        } // End of the AddSupplierInvoiceRows method
        } // End of the AddOfferRows method

        /// <summary>
        /// Add order rows recursively
        /// </summary>
        private async Task AddOrderRows(IList<ProductRow> product_rows, IList<OrderRow> order_rows)
        {
            // Loop product rows
            foreach (ProductRow row in product_rows)
            {
                // Unit
                if (string.IsNullOrEmpty(row.unit_code) == false)
                {
                    row.unit_code = CommonTools.ConvertToAlphanumeric(row.unit_code).ToLower();
                    await AddUnit(row.unit_code);
                }

                // Article, add if there is an identifier
                ArticleRoot article_root = null;
                if (string.IsNullOrEmpty(row.product_code) == false || string.IsNullOrEmpty(row.manufacturer_code) == false || string.IsNullOrEmpty(row.gtin) == false)
                {
                    article_root = await AddArticle(row);
                }

                // Add a order row
                order_rows.Add(new OrderRow
                {
                    ArticleNumber = article_root != null ? article_root.Article.ArticleNumber : null,
                    Description = row.product_name,
                    OrderedQuantity = row.quantity,
                    DeliveredQuantity = row.quantity,
                    Price = row.unit_price,
                    Unit = article_root != null ? article_root.Article.Unit : row.unit_code
                });

                // Check if there is sub rows
                if (row.subrows != null && row.subrows.Count > 0)
                {
                    await AddOrderRows(row.subrows, order_rows);
                }
            }

        } // End of the AddOrderRows method
        } // 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
        } // End of the AddOffer method

        /// <summary>
        /// Add an order
        /// </summary>
        public async Task<OrderRoot> AddOrder(string dox_email, AnnytabDoxTrade doc)
        {
            // Terms of delivery
            if (string.IsNullOrEmpty(doc.terms_of_delivery) == false)
            {
                doc.terms_of_delivery = CommonTools.ConvertToAlphanumeric(doc.terms_of_delivery).ToUpper();
                await AddTermsOfDelivery(doc.terms_of_delivery);
            }

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

            // Way of delivery
            if (string.IsNullOrEmpty(doc.mode_of_delivery) == false)
            {
                doc.mode_of_delivery = CommonTools.ConvertToAlphanumeric(doc.mode_of_delivery).ToUpper();
                await AddWayOfDelivery(doc.mode_of_delivery);
            }

            // Currency
            if (string.IsNullOrEmpty(doc.currency_code) == false)
            {
                doc.currency_code = doc.currency_code.ToUpper();
                await AddCurrency(doc.currency_code);
            }

            // Upsert the customer
            CustomerRoot customer_root = await UpsertCustomer(dox_email, doc);

            // Return if the customer is null
            if (customer_root == null || customer_root.Customer == null)
            {
                return null;
            }

            // Create a list with order rows
            IList<OrderRow> rows = new List<OrderRow>();

            // Add order rows
            if (doc.product_rows != null)
            {
                await AddOrderRows(doc.product_rows, rows);
            }

            // Create an order
            OrderRoot root = new OrderRoot
            {
                Order = new Order
                {
                    CustomerNumber = customer_root.Customer.CustomerNumber,
                    OrderDate = string.IsNullOrEmpty(doc.issue_date) == false ? doc.issue_date : null,
                    DeliveryDate = string.IsNullOrEmpty(doc.delivery_date) == false ? doc.delivery_date : null,
                    YourOrderNumber = doc.buyer_references != null && doc.buyer_references.ContainsKey("order_id") ? doc.buyer_references["order_id"] : null,
                    ExternalInvoiceReference1 = string.IsNullOrEmpty(doc.payment_reference) == false ? doc.payment_reference : null,
                    ExternalInvoiceReference2 = string.IsNullOrEmpty(doc.id) == false ? doc.id : null,
                    Comments = doc.comment,
                    OrderRows = rows,
                    Currency = doc.currency_code,
                    VATIncluded = false
                }
            };

            // Add the order
            FortnoxResponse<OrderRoot> fr = await this.nox_client.Add<OrderRoot>(root, "orders");

            // Log errors
            if (string.IsNullOrEmpty(fr.error) == false)
            {
                this.logger.LogError(fr.error);
            }

            // Return the order
            return fr.model;

        } // End of the AddOrder method
        } // End of the AddAccount method

        /// <summary>
        /// Add an article if it does not exist
        /// </summary>
        public async Task<ArticleRoot> AddArticle(ProductRow row)
        {
            // Create a reference to an article root
            FortnoxResponse<ArticleRoot> fr = new FortnoxResponse<ArticleRoot>();

            // Make sure that the product code only consists of alphanumeric characters
            row.product_code = string.IsNullOrEmpty(row.product_code) == false ? CommonTools.ConvertToAlphanumeric(row.product_code) : null;

            // Find the article
            if (string.IsNullOrEmpty(row.gtin) == false)
            {
                // Try to get articles on EAN
                FortnoxResponse<ArticlesRoot> fr_page = await this.nox_client.Get<ArticlesRoot>($"articles?ean={row.gtin}");

                // Log errors
                if (string.IsNullOrEmpty(fr_page.error) == false)
                {
                    this.logger.LogError(fr_page.error);
                }

                // Make sure that at least one article was found
                if (fr_page.model != null && fr_page.model.Articles != null && fr_page.model.Articles.Count > 0)
                {
                    // Get an article
                    fr = await this.nox_client.Get<ArticleRoot>($"articles/{fr_page.model.Articles[0].ArticleNumber}");

                    // Log errors
                    if (string.IsNullOrEmpty(fr.error) == false)
                    {
                        this.logger.LogError(fr.error);
                    }
                }
            }
            if(fr.model == null && string.IsNullOrEmpty(row.manufacturer_code) == false)
            {
                // Try to get articles on manufacturer code
                FortnoxResponse<ArticlesRoot> fr_page = await this.nox_client.Get<ArticlesRoot>($"articles?manufacturerarticlenumber={row.manufacturer_code}");

                // Log errors
                if (string.IsNullOrEmpty(fr_page.error) == false)
                {
                    this.logger.LogError(fr_page.error);
                }

                // Make sure that at least one article was found
                if (fr_page.model != null && fr_page.model.Articles != null && fr_page.model.Articles.Count > 0)
                {
                    // Get an article
                    fr = await this.nox_client.Get<ArticleRoot>($"articles/{fr_page.model.Articles[0].ArticleNumber}");

                    // Log errors
                    if (string.IsNullOrEmpty(fr.error) == false)
                    {
                        this.logger.LogError(fr.error);
                    }
                }
            }
            if(fr.model == null && string.IsNullOrEmpty(row.product_code) == false)
            {
                // Get an article
                fr = await this.nox_client.Get<ArticleRoot>($"articles/{row.product_code}");

                // Log errors
                if (string.IsNullOrEmpty(fr.error) == false)
                {
                    this.logger.LogError(fr.error);
                }
            }

            // Add the article if it does not exist
            if (fr.model == null)
            {
                // Create a new article
                fr.model = new ArticleRoot
                {
                    Article = new Article
                    {
                        ArticleNumber = string.IsNullOrEmpty(row.product_code) == false ? row.product_code : null,
                        ConstructionAccount = this.default_values.SalesAccountSEREVERSEDVAT,
                        Description = row.product_name,
                        EAN = string.IsNullOrEmpty(row.gtin) == false ? row.gtin : null,
                        EUAccount = this.default_values.SalesAccountEUREVERSEDVAT,
                        EUVATAccount = this.default_values.SalesAccountEUVAT,
                        ExportAccount = this.default_values.SalesAccountEXPORT,
                        ManufacturerArticleNumber = string.IsNullOrEmpty(row.manufacturer_code) == false ? row.manufacturer_code : null,
                        PurchaseAccount = this.default_values.PurchaseAccount,
                        SalesAccount = CommonTools.GetArticleSalesAccount(row.vat_rate, this.default_values),
                        Unit = string.IsNullOrEmpty(row.unit_code) == false ? row.unit_code : null
                    }
                };

                // Add an article
                fr = await this.nox_client.Add<ArticleRoot>(fr.model, "articles");

                // Log errors
                if (string.IsNullOrEmpty(fr.error) == false)
                {
                    this.logger.LogError(fr.error);
                }

                // Add a default price
                if (fr.model != null)
                {
                    PriceRoot price = new PriceRoot
                    {
                        Price = new Price
                        {
                            ArticleNumber = fr.model.Article.ArticleNumber,
                            PriceList = this.default_values.PriceList,
                            FromQuantity = 0,
                            Amount = row.unit_price
                        }
                    };

                    // Add a price
                    FortnoxResponse<PriceRoot> fr_price = await this.nox_client.Add<PriceRoot>(price, "prices");

                    // Log errors
                    if (string.IsNullOrEmpty(fr_price.error) == false)
                    {
                        this.logger.LogError(fr_price.error);
                    }
                }     
            }

            // Return the post
            return fr.model;

        } // End of the AddArticle method