Beispiel #1
0
        //将分期添加到task队列中
        /// <summary>
        ///     添加s the stages list to queue.
        /// </summary>
        /// <param name="isAddContributionChangeToQueue">if set to <c>true</c> [is 添加 contribution change to queue].</param>
        /// <param name="parameter">参数</param>
        /// <param name="resultList">The result list.</param>
        protected void AddStagesListToQueue(bool isAddContributionChangeToQueue, IList <FenRunResultParameter> parameter,
                                            IList <ITaskResult> resultList)
        {
            if (Configuration.StageRule.StagePeriods > 1)
            {
                var timeList = GetTimeList();
                for (var i = 0; i < Configuration.StageRule.StagePeriods; i++)
                {
                    IList <FenRunResultParameter> parametertmpList = new List <FenRunResultParameter>();
                    foreach (var item in parameter)
                    {
                        var para = new FenRunResultParameter(item)
                        {
                            Amount     = item.Amount / Configuration.StageRule.StagePeriods,
                            UserRemark = $"第{i + 1}期"
                        };
                        parametertmpList.Add(para);
                    }

                    var ResultParameter = new FenRunStagesResultParameter
                    {
                        // IsAddContributionChangeToQueue = isAddContributionChangeToQueue,
                        // IsAddIncomeChangeToQueue = Configuration.IsAddIncomeChangeToQueue,
                        FenRunResultParameterList = parametertmpList
                    };
                    var queueResult = new TaskExecutes.ResultModel.TaskQueueResult <FenRunStagesResultParameter>(Context)
                    {
                        //  ModuleId = new Guid(FenRunStagesResultDealwithModule.Id),
                        UserId        = 0,
                        Parameter     = ResultParameter,
                        ExecutionTime = timeList[i]
                    };
                    resultList.Add(queueResult);
                }
            }
            else
            {
                foreach (var item in parameter)
                {
                    var account = Ioc.Resolve <IAccountService>().GetAccount(item.ReceiveUserId, item.MoneyTypeId);
                    if (account == null)
                    {
                        continue;
                    }

                    var moneyType = Ioc.Resolve <IAutoConfigService>().GetList <MoneyTypeConfig>()
                                    .FirstOrDefault(r => r.Id == item.MoneyTypeId);
                    //AddContributionChangeToQueue(item.ReceiveUserId, moneyType, item.Amount, resultList);
                    resultList.Add(new AssetTaskResult(Context)
                    {
                        UserId = item.ReceiveUserId, AccountId = account.Id, ChangeAmount = item.Amount
                    });
                    var invoiceResult = new InvoiceResult(Context)
                    {
                        Parameter = item
                    };
                    resultList.Add(invoiceResult);
                }
            }
        }
Beispiel #2
0
        public ActionResult GenerateInvoice(string itemIds)
        {
            var viewModel = new InvoiceResult();

            viewModel.InvoiceTable = CreateInvoiceTablelContent(itemIds);
            return(View("InvoiceTemplate", viewModel));
        }
Beispiel #3
0
 public void OnGet()
 {
     if (HttpContext.Session.GetString("Invoices") == null)
     {
         var oauthUrl = dispatchService.XeroOAuthUrl();
         Redirect(oauthUrl);
     }
     else
     {
         InvoiceResult          = System.Text.Json.JsonSerializer.Deserialize <InvoiceResult>(HttpContext.Session.GetString("Invoices"));
         InvoiceResult.Invoices = InvoiceResult.Invoices.Where(row => DateTime.Parse(row.DateString) >= DateTime.Now).ToList();
     }
 }
Beispiel #4
0
        public async Task <InvoiceResult> InvoiceDeleted(Invoice invoice)
        {
            _logger.LogInformation(GetLogMessage("{invoice}"), invoice.Id);


            var retVal = new InvoiceResult {
                InvoiceId = invoice.Id
            };


            var entity = await _invoices.Queryable()
                         .Include(x => x.Lines)
                         .Include(x => x.ProjectInvoice)
                         .Where(x => x.Id == invoice.Id)
                         .FirstOrDefaultAsync();


            if (invoice.Metadata.ContainsKey("proj_id"))
            {
                Guid projectId = Guid.Parse(invoice.Metadata["proj_id"]);

                retVal.ProjectId = projectId;

                foreach (var x in entity.Lines)
                {
                    x.ObjectState = ObjectState.Deleted;
                }
            }
            else
            {
                _logger.LogDebug(GetLogMessage("Not a project invoice"));
            }

            entity.IsDeleted   = true;
            entity.ObjectState = ObjectState.Modified;


            var records = _invoices.InsertOrUpdateGraph(entity, true);

            _logger.LogInformation(GetLogMessage("{0} Invoice Records updated"), records);

            if (records > 0)
            {
                retVal.Succeeded = true;
            }

            return(retVal);
        }
Beispiel #5
0
        public override bool BeforePrint()
        {
            #region To do something

            INV_InvoiceBl        invoiceBl = new INV_InvoiceBl();
            INV_InvoiceHeaderDto updateDto = ((INV_InvoiceHeaderDto)this.Dto);
            updateDto.Status = CommonData.InvoiceStatus.Printed;
            InvoiceResult result = invoiceBl.UpdateInvoiceData(updateDto);

            #endregion

            //recognized variable to handle result
            this.ReturnCode = result.ReturnCode;

            if (result.ReturnCode == CommonData.DbReturnCode.Succeed)
            {
                return(true);
            }
            return(false);
        }
        private async Task <InvoiceResult> VoidInvoice(ProjectInvoice invoice)
        {
            var retVal = new InvoiceResult()
            {
                InvoiceId = invoice.InvoiceId
            };

            var service = new InvoiceService();
            var result  = service.VoidInvoice(invoice.InvoiceId);

            if (result.Status == "void")
            {
                retVal.Succeeded = true;
                await Task.Run(() => RaiseEvent(new InvoiceVoidedEvent()
                {
                    InvoiceId = invoice.InvoiceId
                }));
            }

            return(retVal);
        }
        private async Task <InvoiceResult> FinalizeInvoice([NotNull] ProjectInvoice entity)
        {
            _logger.LogInformation($@"Finalizing Invoice: {entity.InvoiceId}");
            var retVal = new InvoiceResult()
            {
                InvoiceId = entity.InvoiceId,
                ProjectId = entity.ProjectId
            };

            var invoice = _invoiceService.FinalizeInvoice(entity.InvoiceId, new InvoiceFinalizeOptions());

            _logger.LogInformation($@"Invoice Status: {invoice.Status}");

            if (invoice.Status == "open")
            {
                retVal.Succeeded = true;
                await Task.Run(() => RaiseEvent(new InvoiceFinalizedEvent()
                {
                    InvoiceId = entity.InvoiceId
                }));
            }

            return(retVal);
        }
Beispiel #8
0
        public async Task <InvoiceResult> InvoiceCreated(Invoice invoice, string refNo)
        {
            _logger.LogInformation(GetLogMessage("Invoice: {invoice}"), invoice.Id);

            var retVal = new InvoiceResult
            {
                InvoiceId = invoice.Id
            };

            var entity = new StripeInvoice
            {
                Id               = invoice.Id,
                ObjectState      = ObjectState.Added,
                Updated          = DateTimeOffset.UtcNow,
                AmountDue        = Convert.ToDecimal(invoice.AmountDue / 100m),
                AmountRemaining  = Convert.ToDecimal(invoice.AmountRemaining / 100m),
                Attempted        = invoice.Attempted,
                CustomerId       = invoice.CustomerId,
                InvoicePdf       = invoice.InvoicePdf,
                Status           = invoice.Status,
                SubscriptionId   = invoice.SubscriptionId,
                AmountPaid       = Convert.ToDecimal(invoice.AmountPaid / 100m),
                Total            = Convert.ToDecimal(invoice.Total / 100m),
                Subtotal         = Convert.ToDecimal(invoice.Subtotal / 100m),
                HostedInvoiceUrl = invoice.HostedInvoiceUrl,
                BillingReason    = invoice.BillingReason,
                AttemptCount     = invoice.AttemptCount,
                Number           = invoice.Number,
                DueDate          = invoice.DueDate
            };


            if (invoice.Metadata.ContainsKey("proj_id"))
            {
                Guid projectId = Guid.Parse(invoice.Metadata["proj_id"]);
                _logger.LogInformation(GetLogMessage("Project Id : {0}"), projectId.ToString());

                var project = await _projectService.Repository.Queryable()
                              .Where(x => x.Id == projectId).FirstAsync();

                retVal.ProjectId = projectId;

                entity.ProjectInvoice = new ProjectInvoice()
                {
                    AccountManagerId       = project.AccountManagerId,
                    ProviderOrganizationId = project.ProjectManagerOrganizationId,
                    CustomerId             = project.CustomerId,
                    BuyerOrganizationId    = project.CustomerOrganizationId,
                    ProjectManagerId       = project.ProjectManagerId,
                    ProjectId   = projectId,
                    RefNo       = refNo,
                    ObjectState = ObjectState.Added
                };
            }
            else
            {
                _logger.LogDebug(GetLogMessage("Not a project invoice"));
            }

            var records = _invoices.InsertOrUpdateGraph(entity, true);

            _logger.LogDebug(GetLogMessage("{0} records updated"), records);

            if (records > 0)
            {
                UpdateInvoiceItems(invoice, true);
                retVal.Succeeded = true;
            }

            return(await Task.FromResult(retVal));
        }
Beispiel #9
0
        public async Task <InvoiceResult> InvoicePaymentSucceeded(Invoice invoice)
        {
            _logger.LogInformation(GetLogMessage("Invoice Id : {invoice}"), invoice.Id);

            _logger.LogInformation(GetLogMessage("Invoice Metadata : {0}"), invoice.Metadata);

            var entity = await _invoices.Queryable()
                         .Include(x => x.Items)
                         .ThenInclude(x => x.TimeEntries)
                         .Include(x => x.Items)
                         .ThenInclude(x => x.IndividualPayoutIntents)
                         .Include(x => x.Items)
                         .ThenInclude(x => x.OrganizationPayoutIntents)
                         .Include(x => x.Items)
                         .ThenInclude(x => x.Contract)
                         .Where(x => x.Id == invoice.Id)
                         .FirstOrDefaultAsync();

            if (entity == null)
            {
                throw new ApplicationException("Invoice not found. Invoice Id : " + invoice.Id);
            }

            var retVal = new InvoiceResult {
                InvoiceId = invoice.Id
            };

            if (invoice.Metadata.ContainsKey("proj_id"))
            {
                Guid projectId = Guid.Parse(invoice.Metadata["proj_id"]);

                retVal.ProjectId = projectId;
                var processableTimeEntries = entity.Items.SelectMany(x => x.TimeEntries).ToList();

                _logger.LogDebug(GetLogMessage("Time Entries to Process: {0}"), processableTimeEntries.Count);

                foreach (var timeEntry in processableTimeEntries)
                {
                    var originalStatus = timeEntry.Status;

                    if (originalStatus != TimeStatus.PendingPayout)
                    {
                        timeEntry.Status      = TimeStatus.PendingPayout;
                        timeEntry.Updated     = DateTimeOffset.UtcNow;
                        timeEntry.ObjectState = ObjectState.Modified;

                        timeEntry.StatusTransitions.Add(new TimeEntryStatusTransition()
                        {
                            Status      = TimeStatus.PendingPayout,
                            ObjectState = ObjectState.Added
                        });
                    }
                }

                _logger.LogDebug(GetLogMessage("Invoice Items to Process: {0}"), entity.Items.Count);


                foreach (var item in entity.Items)
                {
                    var totalAccountManagerStream = item.TimeEntries.Sum(x => x.TotalAccountManagerStream);
                    if (totalAccountManagerStream > 0)
                    {
                        item.IndividualPayoutIntents.Add(new IndividualPayoutIntent
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.AccountManagerOrganizationId,
                            PersonId       = item.Contract.AccountManagerId,
                            Amount         = item.TimeEntries.Sum(x => x.TotalAccountManagerStream),
                            Type           = CommissionType.AccountManagerStream,
                            InvoiceItemId  = item.Id,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added
                        });
                    }
                    else
                    {
                        _logger.LogDebug(GetLogMessage("No project manager stream added"));
                    }


                    var totalProjectManagerStream = item.TimeEntries.Sum(x => x.TotalProjectManagerStream);
                    if (totalProjectManagerStream > 0)
                    {
                        item.IndividualPayoutIntents.Add(new IndividualPayoutIntent
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.ProjectManagerOrganizationId,
                            PersonId       = item.Contract.ProjectManagerId,
                            Amount         = item.TimeEntries.Sum(x => x.TotalProjectManagerStream),
                            Type           = CommissionType.ProjectManagerStream,
                            InvoiceItemId  = item.Id,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added
                        });
                    }
                    else
                    {
                        _logger.LogDebug(GetLogMessage("No project manager stream added"));
                    }



                    var totalContractorStream = item.TimeEntries.Sum(x => x.TotalContractorStream);
                    if (totalContractorStream > 0)
                    {
                        item.IndividualPayoutIntents.Add(new IndividualPayoutIntent
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.ContractorOrganizationId,
                            PersonId       = item.Contract.ContractorId,
                            Amount         = item.TimeEntries.Sum(x => x.TotalContractorStream),
                            Type           = CommissionType.ContractorStream,
                            InvoiceItemId  = item.Id,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added
                        });
                    }
                    else
                    {
                        _logger.LogDebug(GetLogMessage("No contractor stream added"));
                    }


                    var totalRecruiterStream = item.TimeEntries.Sum(x => x.TotalRecruiterStream);
                    if (totalRecruiterStream > 0)
                    {
                        item.IndividualPayoutIntents.Add(new IndividualPayoutIntent
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.RecruiterOrganizationId,
                            PersonId       = item.Contract.RecruiterId,
                            Amount         = item.TimeEntries.Sum(x => x.TotalRecruiterStream),
                            Type           = CommissionType.RecruiterStream,
                            InvoiceItemId  = item.Id,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added
                        });
                    }
                    else
                    {
                        _logger.LogDebug(GetLogMessage("No recruiter stream added"));
                    }


                    var totalMarketerStream = item.TimeEntries.Sum(x => x.TotalMarketerStream);
                    if (totalMarketerStream > 0)
                    {
                        item.IndividualPayoutIntents.Add(new IndividualPayoutIntent
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.MarketerOrganizationId,
                            PersonId       = item.Contract.MarketerId,
                            Amount         = totalMarketerStream,
                            Type           = CommissionType.MarketerStream,
                            InvoiceItemId  = item.Id,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added
                        });
                    }

                    var totalMarketingAgencyStream = item.TimeEntries.Sum(x => x.TotalMarketingAgencyStream);
                    if (totalMarketingAgencyStream > 0)
                    {
                        item.OrganizationPayoutIntents.Add(new OrganizationPayoutIntent()
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.MarketerOrganizationId,
                            Amount         = totalMarketingAgencyStream,
                            Type           = CommissionType.MarketingAgencyStream,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added,
                            InvoiceItemId  = item.Id
                        });
                    }
                    else
                    {
                        _logger.LogDebug(GetLogMessage("No marketing agency stream added"));
                    }

                    var totalRecruitingAgencyStream = item.TimeEntries.Sum(x => x.TotalRecruitingAgencyStream);
                    if (totalRecruitingAgencyStream > 0)
                    {
                        item.OrganizationPayoutIntents.Add(new OrganizationPayoutIntent()
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.RecruiterOrganizationId,
                            Amount         = item.TimeEntries.Sum(x => x.TotalRecruitingAgencyStream),
                            Type           = CommissionType.RecruitingAgencyStream,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added,
                            InvoiceItemId  = item.Id
                        });
                    }
                    else
                    {
                        _logger.LogDebug(GetLogMessage("No recruiting agency stream added"));
                    }

                    var totalAgencyStream = item.TimeEntries.Sum(x => x.TotalAgencyStream);
                    if (totalAgencyStream > 0)
                    {
                        item.OrganizationPayoutIntents.Add(new OrganizationPayoutIntent()
                        {
                            InvoiceId      = item.InvoiceId,
                            OrganizationId = item.Contract.ContractorOrganizationId,
                            Amount         = totalAgencyStream,
                            Type           = CommissionType.ProviderAgencyStream,
                            Description    = item.Description,
                            ObjectState    = ObjectState.Added,
                            InvoiceItemId  = item.Id
                        });
                    }

                    item.ObjectState = ObjectState.Modified;
                }
            }
            else
            {
                _logger.LogDebug(GetLogMessage("Not a project invoice"));
            }

            entity.Updated               = DateTimeOffset.UtcNow;
            entity.Id                    = invoice.Id;
            entity.AmountDue             = Convert.ToDecimal(invoice.AmountDue / 100m);
            entity.AmountRemaining       = Convert.ToDecimal(invoice.AmountRemaining / 100m);
            entity.Attempted             = invoice.Attempted;
            entity.CustomerId            = invoice.CustomerId;
            entity.InvoicePdf            = invoice.InvoicePdf;
            entity.Status                = invoice.Status;
            entity.SubscriptionId        = invoice.SubscriptionId;
            entity.AmountPaid            = Convert.ToDecimal(invoice.AmountPaid / 100m);
            entity.Total                 = Convert.ToDecimal(invoice.Total / 100m);
            entity.Subtotal              = Convert.ToDecimal(invoice.Subtotal / 100m);
            entity.HostedInvoiceUrl      = invoice.HostedInvoiceUrl;
            entity.BillingReason         = invoice.BillingReason;
            entity.AttemptCount          = invoice.AttemptCount;
            entity.Number                = invoice.Number;
            entity.ObjectState           = ObjectState.Modified;
            entity.StripePaymentIntentId = invoice.PaymentIntentId;

            var records = _invoices.InsertOrUpdateGraph(entity, true);

            _logger.LogDebug(GetLogMessage("{0} Invoice Records updated"), records);

            if (records > 0)
            {
                retVal.Succeeded = true;
            }

            return(retVal);
        }
Beispiel #10
0
        public async Task <InvoiceResult> InvoiceUpdated(Invoice invoice)
        {
            _logger.LogInformation(GetLogMessage("Invoice Id : {invoice}"), invoice.Id);
            _logger.LogInformation(GetLogMessage("Invoice Metadata : {0}"), invoice.Metadata);

            var entity = await _invoices.Queryable()
                         .Include(x => x.Lines)
                         .Include(x => x.ProjectInvoice)
                         .Where(x => x.Id == invoice.Id)
                         .FirstOrDefaultAsync();

            if (entity == null)
            {
                throw new ApplicationException("Invoice not found. Invoice Id :" + invoice.Id);
            }

            var retVal = new InvoiceResult {
                InvoiceId = invoice.Id
            };

            if (invoice.Metadata.ContainsKey("proj_id"))
            {
                Guid projectId = Guid.Parse(invoice.Metadata["proj_id"]);

                retVal.ProjectId = projectId;
            }
            else
            {
                _logger.LogDebug(GetLogMessage("Not a project invoice"));
            }

            // mark as deleted unless they are preserved
            foreach (var x in entity.Lines)
            {
                x.ObjectState = ObjectState.Deleted;
            }

            foreach (var line in invoice.Lines)
            {
                var li = entity.Lines.FirstOrDefault(x => x.Id == line.Id);
                if (li != null)
                {
                    li.ObjectState = ObjectState.Modified;
                }
                else
                {
                    li = new StripeInvoiceLine
                    {
                        ObjectState = ObjectState.Added
                    };

                    entity.Lines.Add(li);
                }

                li.InvoiceId   = invoice.Id;
                li.PeriodEnd   = line.Period.End;
                li.PeriodStart = line.Period.Start;
                li.Amount      = Convert.ToDecimal(line.Amount / 100m);

                li.InjectFrom(line);
            }

            UpdateInvoiceItems(invoice);

            entity.InjectFrom(invoice);

            entity.Updated         = DateTimeOffset.UtcNow;
            entity.Id              = invoice.Id;
            entity.AmountDue       = Convert.ToDecimal(invoice.AmountDue / 100m);
            entity.AmountRemaining = Convert.ToDecimal(invoice.AmountRemaining / 100m);
            entity.AmountPaid      = Convert.ToDecimal(invoice.AmountPaid / 100m);
            entity.Total           = Convert.ToDecimal(invoice.Total / 100m);
            entity.Subtotal        = Convert.ToDecimal(invoice.Subtotal / 100m);

            entity.Attempted        = invoice.Attempted;
            entity.CustomerId       = invoice.CustomerId;
            entity.InvoicePdf       = invoice.InvoicePdf;
            entity.Status           = invoice.Status;
            entity.SubscriptionId   = invoice.SubscriptionId;
            entity.HostedInvoiceUrl = invoice.HostedInvoiceUrl;
            entity.BillingReason    = invoice.BillingReason;
            entity.AttemptCount     = invoice.AttemptCount;
            entity.Number           = invoice.Number;
            entity.ObjectState      = ObjectState.Modified;

            var records = _invoices.InsertOrUpdateGraph(entity, true);

            _logger.LogDebug(GetLogMessage("{0} invoice records updated"), records);

            if (records > 0)
            {
                retVal.Succeeded = true;
            }

            return(retVal);
        }
Beispiel #11
0
        public async Task <InvoiceResult> CreateInvoiceAsync(InvoiceInfo info)
        {
            var api = await GetApiAsync();

            if (api.Client == null)
            {
                throw new InvoicingException("Did not find PowerOffice Client");
            }

            var result   = new InvoiceResult();
            var customer = await CreateCustomerIfNotExistsAsync(info, result);

            _logger.LogInformation("* Bruker kunde med epost: {CustomerEmailAddress}, id {CustomerId}",
                                   customer.EmailAddress, customer.Id);

            await CreateProductsIfNotExistsAsync(info);

            var invoice = new OutgoingInvoice
            {
                Status            = OutgoingInvoiceStatus.Draft,
                OrderDate         = info.OrderDate?.ToDateTimeUnspecified(),
                ContractNo        = info.OrderId,
                CustomerReference = info.CustomerInvoiceReference,
                CustomerCode      = customer.Code
            };

            if (!string.IsNullOrWhiteSpace(info.ProjectCode))
            {
                invoice.ProjectCode = info.ProjectCode;
            }

            foreach (var line in info.Lines)
            {
                if (line.Type == InvoiceLineType.Text)
                {
                    invoice.OutgoingInvoiceLines.Add(
                        new OutgoingInvoiceLine
                    {
                        LineType    = VoucherLineType.Text,
                        Description = line.Description
                    });
                }
                else
                {
                    var invoiceLine = new OutgoingInvoiceLine
                    {
                        LineType    = VoucherLineType.Normal,
                        ProductCode = line.ProductCode,
                        Quantity    = line.Quantity,
                        Description = line.Description,
                        UnitPrice   = line.Price
                    };
                    invoice.OutgoingInvoiceLines.Add(invoiceLine);
                }
            }

            var outgoingInvoice = await api.OutgoingInvoice.SaveAsync(invoice);

            result.InvoiceId = outgoingInvoice.Id.ToString();
            return(result);
        }
Beispiel #12
0
        private async Task <Customer> CreateCustomerIfNotExistsAsync(InvoiceInfo info, InvoiceResult result)
        {
            var api = await GetApiAsync();

            // Search for customer by VAT number
            var rgx       = new Regex("[^0-9]");
            var vatNumber = info.CustomerVatNumber != null?rgx.Replace(info.CustomerVatNumber, "") : null;

            _logger.LogInformation("* VAt number: {VatNumber}", vatNumber);

            var existingCustomer = !string.IsNullOrWhiteSpace(vatNumber)
                ? api.Customer.Get()
                                   .FirstOrDefault(c => c.VatNumber == info.CustomerVatNumber)
                : null;

            var customerEmail = info.CustomerEmail;

            _logger.LogInformation("* Customer email: {CustomerEmail}", customerEmail);

            // If no customer was found by VAT number, then search by email
            if (!string.IsNullOrWhiteSpace(customerEmail))
            {
                existingCustomer ??= api.Customer.Get()
                .FirstOrDefault(c => c.EmailAddress == customerEmail);
            }

            // If we found a customer, return him!
            if (existingCustomer != null)
            {
                result.LogEntries.Add(
                    $"Kunden {existingCustomer.Name} med epost {existingCustomer.EmailAddress} fantes allerede.");
                return(existingCustomer);
            }

            // If not, create the customer
            var customer = new Customer
            {
                EmailAddress        = customerEmail,
                VatNumber           = vatNumber,
                InvoiceEmailAddress = customerEmail,

                MailAddress = new Address
                {
                    Address1    = info.CustomerAddress,
                    City        = info.CustomerCity,
                    ZipCode     = info.CustomerZip,
                    CountryCode = info.CustomerCountry
                }
            };

            customer.Name = info.CustomerName;

            if (info.PaymentMethod == PaymentProvider.PowerOfficeEHFInvoice && !string.IsNullOrWhiteSpace(vatNumber))
            {
                customer.InvoiceDeliveryType = InvoiceDeliveryType.EHF;
            }
            else
            {
                customer.InvoiceDeliveryType = InvoiceDeliveryType.PdfByEmail;
            }

            result.LogEntries.Add($"Kunden {customer.Name} med epost {customer.EmailAddress} ble opprettet.");
            return(await api.Customer.SaveAsync(customer));
        }
        private async Task <InvoiceResult> Create(InvoiceInput input, Guid organizationId)
        {
            _logger.LogInformation(GetLogMessage("{organizationId} with options {@input}"), organizationId, input);

            var retVal = new InvoiceResult()
            {
                ProjectId = input.ProjectId
            };

            var project = await _projectService
                          .Repository.Queryable()
                          .Include(x => x.CustomerAccount)
                          .ThenInclude(x => x.PaymentTerm)
                          .Include(x => x.Contracts)
                          .ThenInclude(x => x.InvoiceItems)
                          .Include(x => x.BuyerOrganization)
                          .ThenInclude(x => x.OrganizationBuyerAccount)
                          .Include(x => x.ProviderOrganization)
                          .Include(x => x.Contracts)
                          .ThenInclude(x => x.TimeEntries)
                          .Include(x => x.Contracts)
                          .ThenInclude(x => x.Contractor)
                          .ThenInclude(x => x.Person)
                          .Include(x => x.ProviderOrganization)
                          .ThenInclude(x => x.Organization)
                          .Include(x => x.Contracts)
                          .ThenInclude(x => x.ProviderOrganization)
                          .ThenInclude(x => x.Organization)
                          .Where(x => x.Id == input.ProjectId && x.ProjectManagerOrganizationId == organizationId)
                          .FirstAsync();

            if (project == null)
            {
                throw new ApplicationException("Project Not Found. Id : " + input.ProjectId + " Organization Id : " + organizationId);
            }

            if (project.BuyerOrganization.OrganizationBuyerAccount == null)
            {
                _logger.LogInformation(GetLogMessage("No buyer account found, creating..."));

                var result = await _buyerAccountService.PushCustomer(project.CustomerOrganizationId, project.CustomerId);

                if (result > 0)
                {
                    _logger.LogDebug(GetLogMessage("{0} records updated in database"), result);

                    return(await Create(input, organizationId));
                }

                retVal.ErrorMessage = "Unable to establish buyer account for customer";
                return(retVal);
            }

            List <Contract> contracts;

            // this could be filtered by active, etc

            if (input.IncludeAllContracts)
            {
                contracts = project.Contracts.ToList();
            }
            else
            {
                contracts = project
                            .Contracts
                            .Where(x => input.ContractIds.Contains(x.Id))
                            .ToList();
            }

            _logger.LogDebug(GetLogMessage("Contracts Found: {contracts}"), contracts.Count);
            _logger.LogDebug(GetLogMessage("Buyer Account: {buyerAcct}"), project
                             .BuyerOrganization.OrganizationBuyerAccount.BuyerAccountId);

            var options = new InvoiceCreateOptions()
            {
                Customer         = project.BuyerOrganization.OrganizationBuyerAccount.BuyerAccountId,
                AutoAdvance      = false,
                CollectionMethod = "send_invoice",
                //DaysUntilDue = project.CustomerAccount.PaymentTerm.NetValue > 0 ? project.CustomerAccount.PaymentTerm.NetValue : 1,
                //Footer = project.Proposal.AgreementText,
                DueDate      = DateTime.Today.AddDays(project.CustomerAccount.PaymentTerm.NetValue > 0 ? project.CustomerAccount.PaymentTerm.NetValue : 1),
                CustomFields = new List <InvoiceCustomFieldOptions>()
                {
                    new InvoiceCustomFieldOptions()
                    {
                        Name  = "Project Name",
                        Value = project.Name
                    },
                    new InvoiceCustomFieldOptions()
                    {
                        Name  = "Provider Company",
                        Value = project.ProviderOrganization.Organization.Name
                    }
                },
                Metadata = new Dictionary <string, string>()
                {
                    { "proj_id", project.Id.ToString() }
                }
            };

            var itemsCreated = 0;
            var itemsUpdated = 0;

            foreach (var c in contracts)
            {
                _logger.LogInformation(GetLogMessage("Contract Id: {0}"), c.Id);

                var timeEntries = c.TimeEntries
                                  .Where(x => x.Status == TimeStatus.Approved && x.InvoiceItemId == null)
                                  .ToList();

                _logger.LogDebug(GetLogMessage("{entries} Approved Entries Found"), timeEntries.Count);

                var totalHours = timeEntries.Sum(x => x.TotalHours);
                if (totalHours > 0)
                {
                    var totalCustomerAmount = timeEntries.Sum(x => x.TotalCustomerAmount);
                    var ancientEntry        = c.TimeEntries.Min(x => x.StartDate);
                    var latterDayEntry      = c.TimeEntries.Max(x => x.EndDate);

                    var hours = totalHours.ToString("F");

                    _logger.LogDebug(GetLogMessage("Hours: {0}"), hours);

                    _logger.LogDebug(GetLogMessage("Amount {amount:C}"), totalCustomerAmount);


                    var description =
                        $@"{hours} Hours Worked by {c.Contractor.Person.DisplayName} [{c.ProviderOrganization.Organization.Name}]";

                    var hasInvoiceItems = c.InvoiceItems.Any(x => x.InvoiceId == null);
                    if (hasInvoiceItems)
                    {
                        var invoiceItems = c.InvoiceItems.Where(x => x.InvoiceId == null);
                        _logger.LogDebug(GetLogMessage("Contract has invoice items : {0}"), invoiceItems.Count());
                        foreach (var item in invoiceItems)
                        {
                            _logger.LogDebug(GetLogMessage("Invoice Item Id : {0}"), item.Id);
                            var stripeItem = _invoiceItemService.Update(item.Id, new InvoiceItemUpdateOptions()
                            {
                                Description = description,
                                Amount      = Convert.ToInt64(totalCustomerAmount * 100m)
                            });

                            if (stripeItem != null)
                            {
                                _logger.LogDebug(GetLogMessage("Item Updated in Stripe. Stripe Item Id : {0}"), stripeItem.Id);
                                itemsUpdated++;
                            }
                            else
                            {
                                _logger.LogDebug(GetLogMessage("Item Update Failed in Stripe"));
                            }
                        }
                    }
                    else
                    {
                        _logger.LogDebug(GetLogMessage("Contract doesn't have invoice items. Creating New Invoice Item"));
                        var invoiceItemOptions = new InvoiceItemCreateOptions()
                        {
                            Period = new InvoiceItemPeriodOptions()
                            {
                                Start = ancientEntry.DateTime,
                                End   = latterDayEntry.DateTime
                            },
                            Customer    = project.BuyerOrganization.OrganizationBuyerAccount.BuyerAccountId,
                            Amount      = Convert.ToInt64(totalCustomerAmount * 100),
                            Currency    = "usd",
                            Description = description,
                            Metadata    = new Dictionary <string, string>()
                            {
                                { "contract-id", c.Id.ToString() }
                            }
                        };

                        _logger.LogInformation(GetLogMessage("options: {0}"), invoiceItemOptions);

                        var invoiceItem = _invoiceItemService.Create(invoiceItemOptions);

                        _logger.LogDebug(GetLogMessage("Invoice Item: {0}"), invoiceItem);

                        var invoiceItemResult = await InvoiceItemCreated(invoiceItem);

                        _logger.LogDebug(GetLogMessage("Invoice Item Result: {@result}"), invoiceItemResult);

                        if (invoiceItemResult.Succeeded)
                        {
                            itemsCreated++;
                        }
                    }

                    if (itemsUpdated + itemsCreated > 0)
                    {
                        c.ObjectState = ObjectState.Modified;
                    }
                }
                else
                {
                    _logger.LogDebug(GetLogMessage("no billable time for {contract}"), c.Id);
                }
            }

            var entriesUpdated = _timeEntries.Commit();

            _logger.LogDebug(GetLogMessage("Entries Updated: {entriesUpdated}"), entriesUpdated);
            if (entriesUpdated == 0)
            {
                _logger.LogWarning(GetLogMessage("No Entities were updated"));
            }

            _logger.LogInformation(GetLogMessage("options: {@Options}"), options);

            var invoice = _invoiceService.Create(options);

            if (invoice != null)
            {
                var stripeResult = await InvoiceCreated(invoice, input.RefNo);

                _logger.LogDebug(GetLogMessage("Stripe Result: {@result}"), stripeResult);

                if (stripeResult.Succeeded)
                {
                    retVal.Succeeded = true;
                    retVal.InvoiceId = invoice.Id;
                }
            }
            else
            {
                _logger.LogDebug(GetLogMessage("Unable to create invoice"));
            }


            if (retVal.Succeeded)
            {
                await Task.Run(() => new InvoiceCreatedEvent()
                {
                    InvoiceId = invoice.Id
                });
            }

            return(retVal);
        }
        public Task <InvoiceResult> InvoiceFinalized(Invoice invoice)
        {
            _logger.LogInformation(GetLogMessage("Invoice: {0}"), invoice.Id);

            var retVal = new InvoiceResult()
            {
                InvoiceId = invoice.Id
            };

            if (invoice.Metadata.ContainsKey("proj_id"))
            {
                retVal.ProjectId = Guid.Parse(invoice.Metadata["proj_id"]);

                var entity = _invoices
                             .Queryable()
                             .Include(x => x.Items)
                             .ThenInclude(x => x.TimeEntries)
                             .First(x => x.Id == invoice.Id);

                entity.InjectFrom(invoice);

                entity.Updated          = DateTimeOffset.UtcNow;
                entity.Id               = invoice.Id;
                entity.AmountDue        = Convert.ToDecimal(invoice.AmountDue / 100m);
                entity.AmountRemaining  = Convert.ToDecimal(invoice.AmountRemaining / 100m);
                entity.Attempted        = invoice.Attempted;
                entity.CustomerId       = invoice.CustomerId;
                entity.InvoicePdf       = invoice.InvoicePdf;
                entity.Status           = invoice.Status;
                entity.SubscriptionId   = invoice.SubscriptionId;
                entity.AmountPaid       = Convert.ToDecimal(invoice.AmountPaid / 100m);
                entity.Total            = Convert.ToDecimal(invoice.Total / 100m);
                entity.Subtotal         = Convert.ToDecimal(invoice.Subtotal / 100m);
                entity.HostedInvoiceUrl = invoice.HostedInvoiceUrl;
                entity.BillingReason    = invoice.BillingReason;
                entity.AttemptCount     = invoice.AttemptCount;
                entity.Attempted        = invoice.Attempted;
                entity.Number           = invoice.Number;
                entity.ObjectState      = ObjectState.Modified;

                var processableTimeEntries = entity.Items.SelectMany(x => x.TimeEntries).ToList();

                _logger.LogDebug(GetLogMessage("Time Entries to Process: {0}"), processableTimeEntries.Count);

                foreach (var timeEntry in processableTimeEntries)
                {
                    var originalStatus = timeEntry.Status;

                    if (originalStatus != TimeStatus.InvoiceSent)
                    {
                        timeEntry.Status      = TimeStatus.InvoiceSent;
                        timeEntry.Updated     = DateTimeOffset.UtcNow;
                        timeEntry.ObjectState = ObjectState.Modified;

                        timeEntry.StatusTransitions.Add(new TimeEntryStatusTransition()
                        {
                            Status      = TimeStatus.InvoiceSent,
                            ObjectState = ObjectState.Added
                        });
                    }
                }

                var records = _invoices.InsertOrUpdateGraph(entity, true);

                _logger.LogDebug(GetLogMessage("{0} Records updated"), records);

                if (records > 0)
                {
                    retVal.Succeeded = true;
                }
            }

            return(Task.FromResult(retVal));
        }
Beispiel #15
0
        public async Task <IActionResult> Index(string invoiceId)
        {
            var model = new InvoiceResult();
            var inv   = await InvoiceRequestRepo.GetInvoice(invoiceId);

            if (inv == null)
            {
                return(NotFound());
            }


            model.OrigAmount    = inv.Amount;
            model.Currency      = inv.Currency;
            model.InvoiceNumber = inv.InvoiceNumber;

            var order = new
            {
                inv.Currency,
                inv.Amount,
                ExchangeCurrency = "BTC",
                OrderId          = inv.InvoiceNumber,
                Markup           = new
                {
                    Percent = 1,
                    Pips    = 10
                }
            };



            var bodyRequest = JsonConvert.SerializeObject(order);
            var strToSign   = string.Format("{0}{1}", MerchantApiKey, bodyRequest);


            var csp  = CreateRsaFromPrivateKey(MerchantPrivateKey);//certificate.GetRSAPrivateKey();
            var sign = Convert.ToBase64String(csp.SignData(Encoding.UTF8.GetBytes(strToSign), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));

            var httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Add("Lykke-Merchant-Id", MerchantId);
            httpClient.DefaultRequestHeaders.Add("Lykke-Merchant-Sign", sign);


            var result = await httpClient.PostAsync(LykkePayOrderUrl,
                                                    new StringContent(bodyRequest, Encoding.UTF8, "application/json"));

            var resp = await result.Content.ReadAsStringAsync();



            if (result.StatusCode != HttpStatusCode.OK)
            {
                return(BadRequest());
            }

            dynamic orderResp = JsonConvert.DeserializeObject(resp);

            model.Amount = orderResp.amount;
            model.QRCode =
                $@"https://chart.googleapis.com/chart?chs=220x220&chld=L|2&cht=qr&chl=bitcoin:{orderResp.address}?amount={orderResp.amount}%26label=LykkePay%26message={orderResp.orderId}";
            return(View(model));
        }