//将分期添加到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); } } }
public ActionResult GenerateInvoice(string itemIds) { var viewModel = new InvoiceResult(); viewModel.InvoiceTable = CreateInvoiceTablelContent(itemIds); return(View("InvoiceTemplate", viewModel)); }
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(); } }
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); }
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); }
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)); }
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); }
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); }
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); }
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)); }
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)); }