Ejemplo n.º 1
0
        private async Task CalculateAmountAndVatAsync(DataProvider.Models.Invoice invoice)
        {
            _logger.LogDebug("Recalculating amount and VAT of invoice {0}", invoice.Id);

            var depositInvoicesTotal = 0.0;

            if (invoice.OrderId != null)
            {
                var query = new QuerySet();
                query.Page.Size = 1000; // TODO we assume 1 order doesn't have more than 1000 deposit invoices. Ideally, we should query by page.
                // don't GetByInvoiceId because invoice might not be persisted yet
                var depositInvoices = await _depositInvoiceDataProvider.GetAllByOrderIdAsync((int)invoice.OrderId, query);

                depositInvoicesTotal = depositInvoices.Items.Select(s => s.IsCreditNote ? s.Amount * -1.0 : s.Amount).Sum() ?? 0.0;
            }

            var baseAmount = invoice.BaseAmount ?? 0.0; // sum of invoicelines (as calculated by frontend)
            var amount     = baseAmount - depositInvoicesTotal;

            var vat = 0.0;

            if (invoice.VatRateId != null)
            {
                // don't GetByInvoiceId because invoice might not be persisted yet
                var vatRate = await _vatRateDataProvider.GetByIdAsync((int)invoice.VatRateId);

                vat = amount * (vatRate.Rate / 100.0);
            }

            invoice.Amount      = amount;       // sum of base amount - all deposit invoices
            invoice.Vat         = vat;          // vat calculated on amount
            invoice.TotalAmount = amount + vat; // gross amount

            _logger.LogDebug("Recalculated amount of invoice {0}: amount {1}} ; vat {2} ; total amount {3}", invoice.Id, invoice.Amount, invoice.Vat, invoice.TotalAmount);
        }
Ejemplo n.º 2
0
        // Note: contact and building of a Case can only be updated through this method
        // UpdateAsync() methods of a resource in OfferManager, OrdereManager, etc. prevent the update of the contact/building for an existing resource
        // That's why we directly call methods of the OfferDataProvider, OrderDataProvider, etc. here
        public async Task UpdateContactAndBuildingAsync(int?contactId, int?buildingId, int?requestId, int?interventionId,
                                                        int?offerId, int?orderId, int?invoiceId)
        {
            int?relativeContactId  = null;
            int?relativeBuildingId = null;

            try
            {
                if (contactId != null)
                {
                    var contact = await _contactDataProvider.GetByIdAsync((int)contactId);

                    relativeContactId = contact.Number;
                }

                if (buildingId != null)
                {
                    var building = await _buildingDataProvider.GetByIdAsync((int)buildingId);

                    relativeBuildingId = building.Number;
                }

                if (requestId != null)
                {
                    await _requestDataProvider.UpdateContactAndBuildingAsync((int)requestId, relativeContactId, relativeBuildingId);
                }

                if (interventionId != null)
                {
                    await _interventionDataProvider.UpdateContactAndBuildingAsync((int)interventionId, relativeContactId, relativeBuildingId);
                }

                if (offerId != null)
                {
                    await _offerDataProvider.UpdateContactAndBuildingAsync((int)offerId, relativeContactId, relativeBuildingId);
                }
                if (orderId != null)
                {
                    // updating the offer automatically updates the contact/building of the order too. No need to do that explicitly here.

                    var query = new QuerySet();
                    query.Page.Size = 1000; // TODO we assume 1 case doesn't have more than 1000 deposit invoices. Ideally, we should query by page.
                    var depositInvoices = await _depositInvoiceDataProvider.GetAllByOrderIdAsync((int)orderId, query);

                    foreach (var depositInvoice in depositInvoices.Items)
                    {
                        await _depositInvoiceDataProvider.UpdateContactAndBuildingAsync(depositInvoice.Id, relativeContactId, relativeBuildingId);
                    }
                }
                if (invoiceId != null)
                {
                    await _invoiceDataProvider.UpdateContactAndBuildingAsync((int)invoiceId, relativeContactId, relativeBuildingId);
                }
            }
            catch (EntityNotFoundException e)
            {
                throw new IllegalArgumentException("IllegalEntity", $"Contact and building cannot be updated: ${e.Message}", e);
            }
        }
Ejemplo n.º 3
0
        public async Task DeleteAsync(int id)
        {
            try
            {
                var invoice = await _invoiceDataProvider.GetByOrderIdAsync(id);

                var message = $"Order {id} cannot be deleted because invoice {invoice.Id} is attached to it.";
                _logger.LogError(message);
                throw new InvalidOperationException(message);
            }
            catch (EntityNotFoundException)
            {
                var pageQuery = new QuerySet();
                pageQuery.Page.Size = 1;

                var depositInvoices = await _depositInvoiceDataProvider.GetAllByOrderIdAsync(id, pageQuery);

                if (depositInvoices.Count > 0)
                {
                    var message = $"Order {id} cannot be deleted because {depositInvoices.Count} deposit-invoices attached to it.";
                    _logger.LogError(message);
                    throw new InvalidOperationException(message);
                }

                var deposits = await _depositDataProvider.GetAllByOrderIdAsync(id, pageQuery);

                if (deposits.Count > 0)
                {
                    var message = $"Order {id} cannot be deleted because {deposits.Count} deposits are attached to it.";
                    _logger.LogError(message);
                    throw new InvalidOperationException(message);
                }

                // TODO reset ordered flag of offerlines on deletion instead of throwing an error?
                var offerlines = await _offerlineDataProvider.GetOrderedByOrderIdAsync(id, pageQuery);

                if (offerlines.Count > 0)
                {
                    var message = $"Order {id} cannot be deleted because {offerlines.Count} ordered offerlines are attached to it.";
                    _logger.LogError(message);
                    throw new InvalidOperationException(message);
                }

                try
                {
                    var order = await _orderDataProvider.GetByIdAsync(id);

                    await _graphApiService.DeleteEventForPlanningAsync(order);

                    await _orderDataProvider.DeleteByIdAsync(id);
                }
                catch (EntityNotFoundException)
                {
                    // Order not found. Nothing should happen.
                }
            }
        }
Ejemplo n.º 4
0
        public async Task <Paged <DepositInvoice> > GetAllByOrderIdAsync(int orderId, QuerySet query)
        {
            if (query.Sort.Field == null)
            {
                query.Sort.Order = SortQuery.ORDER_DESC;
                query.Sort.Field = "number";
            }

            return(await _depositInvoiceDataProvider.GetAllByOrderIdAsync(orderId, query));
        }
Ejemplo n.º 5
0
        public async Task DeleteAsync(int id)
        {
            try
            {
                var invoice = await _invoiceDataProvider.GetByOrderIdAsync(id);

                var message = $"Order {id} cannot be deleted because invoice {invoice.Id} is attached to it.";
                _logger.LogError(message);
                throw new InvalidOperationException(message);
            }
            catch (EntityNotFoundException)
            {
                var pageQuery = new QuerySet();
                pageQuery.Page.Size = 1;

                var depositInvoices = await _depositInvoiceDataProvider.GetAllByOrderIdAsync(id, pageQuery);

                if (depositInvoices.Count > 0)
                {
                    var message = $"Order {id} cannot be deleted because {depositInvoices.Count} deposit-invoices attached to it.";
                    _logger.LogError(message);
                    throw new InvalidOperationException(message);
                }

                var deposits = await _depositDataProvider.GetAllByOrderIdAsync(id, pageQuery);

                if (deposits.Count > 0)
                {
                    var message = $"Order {id} cannot be deleted because {deposits.Count} deposits are attached to it.";
                    _logger.LogError(message);
                    throw new InvalidOperationException(message);
                }

                try
                {
                    var order = await _orderDataProvider.GetByIdAsync(id);

                    await _documentGenerationManager.DeleteOrderDocumentAsync(id);

                    await _documentGenerationManager.DeleteDeliveryNoteAsync(id);

                    await _documentGenerationManager.DeleteProductionTicketTemplateAsync(id);

                    await _documentGenerationManager.DeleteProductionTicketAsync(id);

                    await _orderDataProvider.DeleteByIdAsync(id);
                }
                catch (EntityNotFoundException)
                {
                    // Order not found. Nothing should happen.
                }
            }
        }
Ejemplo n.º 6
0
        private async Task CalculateAmountAndVatAsync(DataProvider.Models.Invoice invoice)
        {
            _logger.LogDebug("Recalculating amount and VAT of invoice {0}", invoice.Id);

            var depositInvoicesTotal = 0.0;

            if (invoice.OrderId != null)
            {
                var query = new QuerySet();
                query.Page.Size = 1000; // TODO we assume 1 order doesn't have more than 1000 deposit invoices. Ideally, we should query by page.
                // don't GetByInvoiceId because invoice might not be persisted yet
                var depositInvoices = await _depositInvoiceDataProvider.GetAllByOrderIdAsync((int)invoice.OrderId, query);

                depositInvoicesTotal = depositInvoices.Items.Select(s => s.Amount).Sum() ?? 0.0;
            }

            var invoiceSupplementsTotal = 0.0;

            if (invoice.Id != 0)  // invoice supplements can only be attached to an existing invoice
            {
                var query = new QuerySet();
                query.Page.Size = 1000; // TODO we assume 1 invoice doesn't have more than 1000 supplements. Ideally, we should query by page.
                var invoiceSupplements = await _invoiceSupplementDataProvider.GetAllByInvoiceIdAsync(invoice.Id, query);

                invoiceSupplementsTotal = invoiceSupplements.Items.Select(s => s.Amount).Sum() ?? 0.0;
            }

            var baseAmount = invoice.BaseAmount ?? 0.0;
            var amount     = baseAmount + invoiceSupplementsTotal - depositInvoicesTotal;

            var vat = 0.0;

            if (invoice.VatRateId != null)
            {
                // don't GetByInvoiceId because invoice might not be persisted yet
                var vatRate = await _vatRateDataProvider.GetByIdAsync((int)invoice.VatRateId);

                vat = amount * (vatRate.Rate / 100.0);
            }

            invoice.Amount      = amount;       // sum of base amount + all invoice supplements - all deposit invoices
            invoice.Vat         = vat;          // vat calculated on amount
            invoice.TotalAmount = amount + vat; // gross amount
        }