public override async Task <Result <int> > Handle(GenerateCommandInvoiceCommand request, CancellationToken cancellationToken)
        {
            Command command = await _context.Commands
                              .SingleOrDefaultAsync(m => m.Id == request.CommandId && m.ShopId == request.ShopId, cancellationToken);

            if (command == null)
            {
                return(NotFound <Command>(request.CommandId));
            }

            if (command.InvoiceId != null)
            {
                return(BadRequest("An invoice already exists for this command"));
            }

            CommandProposal proposal =
                await _context.CommandProposals
                .SingleOrDefaultAsync(
                    m => m.Approved && m.CommandId == request.CommandId, cancellationToken);

            if (proposal == null)
            {
                return(BadRequest("You can't generate an invoice for this command"));
            }

            Invoice invoice = new Invoice(command, proposal);

            await _context.Invoices.AddAsync(invoice, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            return(Ok(invoice.Id));
        }
        public override async Task <Result> Handle(ApproveCommandProposalCommand request, CancellationToken cancellationToken)
        {
            CommandProposal proposal = await _context.CommandProposals
                                       .Include(m => m.Command)
                                       .SingleOrDefaultAsync(m => m.Id == request.CommandProposalId && m.CommandId == request.CommandId, cancellationToken);

            if (proposal == null)
            {
                return(NotFound <CommandProposal>(request.CommandProposalId));
            }

            if (proposal.Command.Status is not CommandStatus.Accepted)
            {
                return(BadRequest($"You can't cancel this command. The status of the command was '{proposal.Command.Status}'"));
            }

            User user = await _user.GetUserAsync();

            string uid = await _context.Shops.Where(m => m.Id == proposal.Command.ShopId).Select(m => m.UserId).SingleOrDefaultAsync(cancellationToken);

            if (proposal.Command.UserId != user.Id && proposal.Command.UserId != uid)
            {
                return(Unauthorized());
            }

            if (await _context.CommandProposals.AnyAsync(m => m.Approved && m.CommandId == request.CommandId,
                                                         cancellationToken))
            {
                return(BadRequest("You can't change the specifications, One proposal have been validated"));
            }

            if (proposal.Approved)
            {
                return(BadRequest("This specification is already approved"));
            }

            if (proposal.UserId == user.Id)
            {
                return(BadRequest("You can't approve your own proposal"));
            }

            proposal.Approved = true;
            Invoice invoice = new Invoice(proposal.Command, proposal);
            await _context.Invoices.AddAsync(invoice, cancellationToken);

            proposal.Command.InvoiceId = invoice.Id;

            _context.CommandProposals.Update(proposal);

            await _context.SaveChangesAsync(cancellationToken);

            return(Ok());
        }
        public override async Task <Result <int> > Handle(CreateCommandProposalCommand request, CancellationToken cancellationToken)
        {
            Command command = await _context.Commands.SingleOrDefaultAsync(m => m.Id == request.CommandId, cancellationToken);

            if (command == null)
            {
                return(NotFound <Command>(request.CommandId));
            }

            User user = await _accessor.GetUserAsync();

            string uid = await _context.Shops.Where(m => m.Id == command.ShopId)
                         .Select(m => m.UserId)
                         .SingleOrDefaultAsync(cancellationToken);

            if (command.UserId != user.Id || command.UserId != uid)
            {
                return(Unauthorized());
            }

            if (command.Status is not CommandStatus.Accepted)
            {
                return(BadRequest($"The status of the command was {command.Status}, you can't create any proposals"));
            }

            if (await _context.CommandProposals.AnyAsync(m => m.Approved && m.CommandId == request.CommandId, cancellationToken))
            {
                return(BadRequest("You can't change the specifications, one proposal has been already approved"));
            }

            CommandProposal proposal = new CommandProposal(command, user, request.Price, request.Specification);

            await _context.CommandProposals.AddAsync(proposal, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            return(Ok(proposal.Id));
        }