Work Flow For Parasut
See for parasut api documentation. Parasut Api Documentation
This documentation explains invoice operation step by step.
Step 1 : Parasut Login
The required parameters for login are stored in the database. Displays key login parameters.
public class InvoiceParameterResponseDto
{
public Guid ParameterId { get; set; }
public string Key { get; set; }
public string Value { get; set; }
}
LoginRequestDto.cs
public class LoginRequestDto
{
public LoginRequestDto()
{
GrantType = "password";
}
[JsonProperty(PropertyName = "client_id")]
public string ClientId { get; set; }
[JsonProperty(PropertyName = "client_secret")]
public string ClientSecret { get; set; }
[JsonProperty(PropertyName = "redirect_uri")]
public string RedirectUri { get; set; }
[JsonProperty(PropertyName = "username")]
public string UserName { get; set; }
[JsonProperty(PropertyName = "password")]
public string Password { get; set; }
[JsonProperty(PropertyName = "grant_type")]
public string GrantType { get; set; }
}
Step 2 : Check the invoice by order number
If have invoice by orderNo throw AlreadyExistException.
#region Check Customer and order number
private async Task InvoiceControlAsync([NotNull] string orderNo, [NotNull] string customerId)
{
if (await _customerInvoiceService.GetCustomerInvoicesAsync(customerId, orderNo) != null)
throw new AlreadyExistException("Only one invoice can be issued with the same order number.");
}
#endregion
Step 3 : Create Customer
Check customer from Parasut. If customer is null insert customer. If not, update the customer.
// outCustomerId = parasutId
if (string.IsNullOrEmpty(outCustomerId))
{
var response = await client.PostAsync(Constants.Parasut.BASE_URL + _companyId + "/" + Constants.Parasut.INCLUDE_CATEGORY, message);
CustomerResponseDto customer = JsonConvert.DeserializeObject<CustomerResponseDto>(await response.Content.ReadAsStringAsync());
outCustomerId = customer.Data.Id;
// Insert Customer
await _customerService.InsertCustomerAsync(new Customer()
{
CustomerId = dto.CustomerId,
OutId = outCustomerId,
InvoiceServiceTypes = InvoiceServiceTypes.Parasut,
ServiceId = serviceId
});
}
else
{
await client.PutAsync(Constants.Parasut.BASE_URL + _companyId + Constants.Parasut.CONTACTS + outCustomerId + Constants.Parasut.INCLUDE_CATEGORY, message);
}
Step 4 : Check Invoice Type for Customer
Check invoice type with tax number.
#region Check E-invoice and E-Archive
public async Task CheckInvoiceTypeAsync(string taxNumber)
{
using (var client = GetHttpClient())
{
var response = await client.GetAsync(Constants.Parasut.BASE_URL + _companyId + "/" + Constants.Parasut.E_INVOICES_INBOXES_FILTER + taxNumber);
var content = JsonConvert.DeserializeObject<InvoiceInBoxResponseDto>(await response.Content.ReadAsStringAsync());
if (content.Data.Count() == 0)
type = InvoiceType.EARCHIVE;
else
{
type = InvoiceType.EINVOICE;
inboxAdress = content.Data.FirstOrDefault().Attributes.EInvoiceAdress;
}
}
}
#endregion
Step 5 : Create Product
If have product from database it uses. If not, new product add. (For Database and parasut)
#region Create Product
public async Task CreateProductAsync(InvoiceDataRequestDto[] dto)
{
for (int i = 0; i < dto.Count(); i++)
{
string outProductId = await _productService.GetOutId(dto[i].ProductId);
if (string.IsNullOrEmpty(outProductId))
{
// step 1 : create product
var json = JsonConvert.SerializeObject(new ProductRequestDto()
{
Data = new ProductsData()
{
Attributes = new Dtos.Request.OperationController.Parasut.Products.Attributes()
{
Name = dto[i].ProductType.Trim(),
VatRate = dto[i].VatRate
}
}
}, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
using (var client = GetHttpClient())
{
var message = new StringContent(json, Encoding.UTF8, Constants.CONTENT_TYPE);
var response = await client.PostAsync(Constants.Parasut.BASE_URL + _companyId + "/" + Constants.Parasut.INCLUDE_PRODUCTS, message);
ProductResponseDto responseDto = JsonConvert.DeserializeObject<ProductResponseDto>(await response.Content.ReadAsStringAsync());
await _productService.InsertProduct(new Product() { OutId = responseDto.Data.Id, ProductId = dto[i].ProductId, ServiceId = serviceId, InvoiceServiceTypes = InvoiceServiceTypes.Parasut });
}
}
}
}
#endregion
Step 6 : Create Sales Invoice
Create Sales Invoice with Products and Customer information.
new SalesInvoiceRequestDto()
{
Data = new Dtos.Request.OperationController.Parasut.SalesInvoice.Data()
{
Attributes = new Dtos.Request.OperationController.Parasut.SalesInvoice.Attributes()
{
OrderNo = dto.OrderNo,
Currency = dto.CurrencyType.ToString(),
ExchangeRate = dto.ExchangeRate,
InvoiceDiscountType = dto.DiscountType == DiscountType.NONE ? string.Empty : dto.DiscountType.ToString().ToLower(),
InvoiceDiscount = dto.DiscountValue,
IssueDate = dto.PaymentDate.ToString(),
DueDate = dto.PaymentDate.ToString(),
OrderDate = dto.PaymentDate.ToString()
},
Relationships = new Dtos.Request.OperationController.Parasut.SalesInvoice.Relationships()
{
Details = new Details()
{ Data = datum },
Contact = new Dtos.Request.OperationController.Parasut.SalesInvoice.Category()
{
Data = new Dat()
{
Id = outCustomerId,
Type = Constants.Parasut.CONTACTS_TYPE
}
}
}
}
}
Step 7 : Signatured Invoice
Generate Signatured invoice by Customer invoice type.
{
"data": {
"id": "string", <-- **Trackable Job Id**
"type": "trackable_jobs",
"attributes": {
"status": "running",
"errors": [
"string"
]
},
"relationships": null
}
}
Step 8 : Trackable Job
Configure schedule task with hangfire. Parameters; Trackable Job Id Api Key
Response
{
"data": {
"id": "string",
"type": "trackable_jobs",
"attributes": {
"status": "running",
"errors": [
"string"
]
},
"relationships": null
}
}
If status 'error' send notifications to slack channel.("#invoice")