/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.CRM.ApiModels;
using ASC.Api.Documents;
using ASC.Common.Web;
using ASC.Core;
using ASC.CRM.Classes;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.CRM.Resources;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Classes;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.Api.CRM
{
public partial class CRMController
{
///
/// Returns the detailed information about the invoice with the ID specified in the request
///
/// Invoice ID
/// Get invoice by ID
/// Invoices
/// Invoice
[Read(@"invoice/{invoiceid:int}")]
public InvoiceDto GetInvoiceByID(int invoiceid)
{
if (invoiceid <= 0) throw new ArgumentException();
var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid);
if (invoice == null) throw new ItemNotFoundException();
if (!CRMSecurity.CanAccessTo(invoice))
{
throw CRMSecurity.CreateSecurityException();
}
return InvoiceDtoHelper.Get(invoice);
}
///
/// Returns the detailed information about the invoice sample
///
/// Get invoice sample
/// Invoices
/// Invoice
[Read(@"invoice/sample")]
public InvoiceDto GetInvoiceSample()
{
var sample = InvoiceDto.GetSample();
sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber();
sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty;
sample.IssueDate = ApiDateTimeHelper.Get(DateTime.UtcNow);
sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30));
sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow);
sample.Currency = CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency);
sample.InvoiceLines.First().Quantity = 1;
return sample;
}
///
/// Returns the json data of the invoice with the ID specified in the request
///
/// Invoice ID
/// Get invoice json data
/// Invoices
/// Json Data
[Read(@"invoice/jsondata/{invoiceid:int}")]
public string GetInvoiceJsonData(int invoiceid)
{
var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid);
if (invoice == null) throw new ItemNotFoundException();
if (!CRMSecurity.CanAccessTo(invoice))
{
throw CRMSecurity.CreateSecurityException();
}
return invoice.JsonData;
}
///
/// Returns the list of invoices matching the creteria specified in the request
///
/// Invoice status
/// Invoice issue date from
/// Invoice issue date to
/// Invoice due date from
/// Invoice due date to
/// Invoice entity type
/// Invoice entity ID
/// Invoice currency
/// Get invoice list
/// Invoices
/// Invoice list
[Read(@"invoice/filter")]
public IEnumerable GetInvoices(
InvoiceStatus? status,
ApiDateTime issueDateFrom,
ApiDateTime issueDateTo,
ApiDateTime dueDateFrom,
ApiDateTime dueDateTo,
String entityType,
int entityid,
String currency
)
{
if (!String.IsNullOrEmpty(entityType) && !(
String.Compare(entityType, "contact", true) == 0 ||
String.Compare(entityType, "opportunity", true) == 0 ||
String.Compare(entityType, "case", true) == 0))
throw new ArgumentException();
IEnumerable result;
InvoiceSortedByType sortBy;
OrderBy invoiceOrderBy;
var searchString = ApiContext.FilterValue;
if (InvoiceSortedByType.TryParse(ApiContext.SortBy, true, out sortBy))
{
invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending);
}
else if (String.IsNullOrEmpty(ApiContext.SortBy))
{
invoiceOrderBy = new OrderBy(InvoiceSortedByType.Number, true);
}
else
{
invoiceOrderBy = null;
}
var fromIndex = (int)ApiContext.StartIndex;
var count = (int)ApiContext.Count;
if (invoiceOrderBy != null)
{
result = ToListInvoiceBaseDtos(
DaoFactory.GetInvoiceDao().GetInvoices(
searchString,
status,
issueDateFrom, issueDateTo,
dueDateFrom, dueDateTo,
ToEntityType(entityType), entityid,
currency,
fromIndex, count,
invoiceOrderBy));
ApiContext.SetDataPaginated();
ApiContext.SetDataFiltered();
ApiContext.SetDataSorted();
}
else
{
result = ToListInvoiceBaseDtos(
DaoFactory.GetInvoiceDao().GetInvoices(
searchString,
status,
issueDateFrom, issueDateTo,
dueDateFrom, dueDateTo,
ToEntityType(entityType), entityid,
currency,
0,
0,
null));
}
int totalCount;
if (result.Count() < count)
{
totalCount = fromIndex + result.Count();
}
else
{
totalCount = DaoFactory.GetInvoiceDao().GetInvoicesCount(
searchString,
status,
issueDateFrom, issueDateTo,
dueDateFrom, dueDateTo,
ToEntityType(entityType), entityid,
currency);
}
ApiContext.SetTotalCount(totalCount);
return result;
}
///
/// Returns the list of all invoices associated with the entity with the ID and type specified in the request
///
/// Invoice entity type
/// Invoice entity ID
/// Get entity invoices
/// Invoices
/// Invoice list
[Read(@"{entityType:regex(contact|person|company|opportunity)}/invoicelist/{entityid:int}")]
public IEnumerable GetEntityInvoices(String entityType, int entityid)
{
if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException();
return ToListInvoiceBaseDtos(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid));
}
///
/// Updates the status of invoices with the IDs specified in the request
///
/// Invoice ID list
/// Status
/// Update invoice group status
/// Invoices
/// KeyValuePair of Invoices and InvoiceItems
[Update(@"invoice/status/{status:int}")]
public KeyValuePair, IEnumerable> UpdateInvoiceBatchStatus(
int[] invoiceids,
InvoiceStatus status
)
{
if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException();
var oldInvoices = DaoFactory.GetInvoiceDao().GetByID(invoiceids).Where(CRMSecurity.CanAccessTo).ToList();
var updatedInvoices = DaoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status);
// detect what really changed
var realUpdatedInvoices = updatedInvoices
.Select(t => oldInvoices.FirstOrDefault(x => x.ID == t.ID && x.Status != t.Status))
.Where(inv => inv != null)
.ToList();
if (realUpdatedInvoices.Any())
{
MessageService.Send(MessageAction.InvoicesUpdatedStatus, MessageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString());
}
var invoiceItemsUpdated = new List();
if (status == InvoiceStatus.Sent || status == InvoiceStatus.Rejected)
{
var invoiceItemsAll = DaoFactory.GetInvoiceItemDao().GetAll();
var invoiceItemsWithTrackInventory = invoiceItemsAll.Where(item => item.TrackInventory).ToList();
if (status == InvoiceStatus.Sent && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0)
{
foreach (var inv in updatedInvoices)
{
if (inv.Status == InvoiceStatus.Sent)
{
//could be changed
var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID);
if (oldInv != null && oldInv.Status == InvoiceStatus.Draft)
{
//was changed to Sent
var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID);
foreach (var line in invoiceLines)
{
var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID);
if (item != null)
{
item.StockQuantity -= line.Quantity;
DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item);
var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID);
if (oldItem != null)
{
invoiceItemsUpdated.Remove(oldItem);
}
invoiceItemsUpdated.Add(item);
}
}
}
}
}
}
if (status == InvoiceStatus.Rejected && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0)
{
foreach (var inv in updatedInvoices)
{
if (inv.Status == InvoiceStatus.Rejected)
{
//could be changed
var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID);
if (oldInv != null && oldInv.Status == InvoiceStatus.Sent)
{
//was changed from Sent to Rejectes
var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID);
foreach (var line in invoiceLines)
{
var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID);
if (item != null)
{
item.StockQuantity += line.Quantity;
DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item);
var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID);
if (oldItem != null)
{
invoiceItemsUpdated.Remove(oldItem);
}
invoiceItemsUpdated.Add(item);
}
}
}
}
}
}
}
var listInvoiceBaseDtos = ToListInvoiceBaseDtos(updatedInvoices);
return new KeyValuePair, IEnumerable>(listInvoiceBaseDtos, invoiceItemsUpdated.ConvertAll(i => InvoiceItemDtoHelper.Get(i)));
}
///
/// Delete the invoice with the ID specified in the request
///
/// Invoice ID
/// Delete invoice
/// Invoices
/// Invoice
[Delete(@"invoice/{invoiceid:int}")]
public InvoiceBaseDto DeleteInvoice(int invoiceid)
{
if (invoiceid <= 0) throw new ArgumentException();
var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid);
if (invoice == null) throw new ItemNotFoundException();
MessageService.Send(MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number);
return InvoiceBaseDtoHelper.Get(invoice);
}
///
/// Deletes the group of invoices with the IDs specified in the request
///
/// Invoice ID list
/// Delete invoice group
/// Invoices
/// Invoice list
[Delete(@"invoice")]
public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids)
{
if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException();
var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray());
MessageService.Send(MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number));
return ToListInvoiceBaseDtos(invoices);
}
///
/// Creates the invoice with the parameters (contactId, consigneeId, etc.) specified in the request
///
/// Invoice number
/// Invoice issue date
/// Invoice template type
/// Invoice contact ID
/// Invoice consignee ID
/// Invoice entity ID
/// Invoice billing address ID
/// Invoice delivery address ID
/// Invoice due date
/// Invoice language
/// Invoice currency
/// Invoice exchange rate
/// Invoice purchase order number
/// Invoice terms
/// Invoice description
/// Invoice lines list
/// Create invoice
/// Invoices
/// Invoice
///
///
///
[Create(@"invoice")]
public InvoiceDto CreateInvoice(
CreateOrUpdateInvoiceInDto inDto
)
{
string number = inDto.Number;
ApiDateTime issueDate = inDto.IssueDate;
int templateType = inDto.TemplateType;
int contactId = inDto.ContactId;
int consigneeId = inDto.ConsigneeId;
int entityId = inDto.EntityId;
int billingAddressID = inDto.BillingAddressID;
int deliveryAddressID = inDto.DeliveryAddressID;
ApiDateTime dueDate = inDto.DueDate;
string language = inDto.Language;
string currency = inDto.Currency;
decimal exchangeRate = inDto.ExchangeRate;
string purchaseOrderNumber = inDto.PurchaseOrderNumber;
string terms = inDto.Terms;
string description = inDto.Description;
IEnumerable invoiceLines = inDto.InvoiceLines;
var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List();
if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException();
var invoice = new Invoice
{
Status = InvoiceStatus.Draft,
Number = number,
IssueDate = issueDate,
TemplateType = (InvoiceTemplateType)templateType,
ContactID = contactId,
ConsigneeID = consigneeId,
EntityType = EntityType.Opportunity,
EntityID = entityId,
DueDate = dueDate,
Language = language,
Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper() : null,
ExchangeRate = exchangeRate,
PurchaseOrderNumber = purchaseOrderNumber,
Terms = terms,
Description = description
};
CRMSecurity.DemandCreateOrUpdate(invoice);
if (billingAddressID > 0)
{
var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID);
if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId)
throw new ArgumentException();
}
if (deliveryAddressID > 0)
{
var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID);
if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId)
throw new ArgumentException();
}
invoice.ID = DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice);
CreateInvoiceLines(invoiceLinesList, invoice);
DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID);
return InvoiceDtoHelper.Get(invoice);
}
private bool IsLinesForInvoiceCorrect(List invoiceLines)
{
foreach (var line in invoiceLines)
{
if (line.InvoiceItemID <= 0 ||
line.Quantity < 0 || line.Price < 0 ||
line.Discount < 0 || line.Discount > 100 ||
line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0)
return false;
if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID))
return false;
if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID))
return false;
if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID))
return false;
}
return true;
}
private List CreateInvoiceLines(List invoiceLines, Invoice invoice)
{
var result = new List();
for (var i = 0; i < invoiceLines.Count; i++)
{
var line = new InvoiceLine
{
ID = 0,
InvoiceID = invoice.ID,
InvoiceItemID = invoiceLines[i].InvoiceItemID,
InvoiceTax1ID = invoiceLines[i].InvoiceTax1ID,
InvoiceTax2ID = invoiceLines[i].InvoiceTax2ID,
SortOrder = i,
Description = invoiceLines[i].Description,
Quantity = invoiceLines[i].Quantity,
Price = invoiceLines[i].Price,
Discount = Convert.ToInt32(invoiceLines[i].Discount)
};
line.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line);
result.Add(line);
}
return result;
}
///
/// Updates the selected invoice with the parameters (contactId, consigneeId, etc.) specified in the request
///
/// Invoice ID
/// Invoice issue date
/// Invoice template type
/// Invoice contact ID
/// Invoice consignee ID
/// Invoice entity ID
/// Invoice billing address ID
/// Invoice delivery address ID
/// Invoice due date
/// Invoice language
/// Invoice currency
/// Invoice exchange rate
/// Invoice purchase order number
/// Invoice terms
/// Invoice description
/// Invoice lines list
/// Update invoice
/// Invoices
/// Invoice
///
///
///
[Update(@"invoice/{id:int}")]
public InvoiceDto UpdateInvoice(
int id,
CreateOrUpdateInvoiceInDto inDto)
{
ApiDateTime issueDate = inDto.IssueDate;
int templateType = inDto.TemplateType;
int contactId = inDto.ContactId;
int consigneeId = inDto.ConsigneeId;
int entityId = inDto.EntityId;
int billingAddressID = inDto.BillingAddressID;
int deliveryAddressID = inDto.DeliveryAddressID;
ApiDateTime dueDate = inDto.DueDate;
string language = inDto.Language;
string currency = inDto.Currency;
decimal exchangeRate = inDto.ExchangeRate;
string purchaseOrderNumber = inDto.PurchaseOrderNumber;
string terms = inDto.Terms;
string description = inDto.Description;
IEnumerable invoiceLines = inDto.InvoiceLines;
var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List();
if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException();
var invoice = DaoFactory.GetInvoiceDao().GetByID(id);
if (invoice == null || !CRMSecurity.CanEdit(invoice)) throw new ItemNotFoundException();
invoice.IssueDate = issueDate;
invoice.TemplateType = (InvoiceTemplateType)templateType;
invoice.ContactID = contactId;
invoice.ConsigneeID = consigneeId;
invoice.EntityType = EntityType.Opportunity;
invoice.EntityID = entityId;
invoice.DueDate = dueDate;
invoice.Language = language;
invoice.Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper() : null; ;
invoice.ExchangeRate = exchangeRate;
invoice.PurchaseOrderNumber = purchaseOrderNumber;
invoice.Terms = terms;
invoice.Description = description;
invoice.JsonData = null;
CRMSecurity.DemandCreateOrUpdate(invoice);
if (billingAddressID > 0)
{
var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID);
if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId)
throw new ArgumentException();
}
if (deliveryAddressID > 0)
{
var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID);
if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId)
throw new ArgumentException();
}
DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice);
DaoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID);
CreateInvoiceLines(invoiceLinesList, invoice);
DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID);
if (Global.CanDownloadInvoices)
{
// PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID);
}
return InvoiceDtoHelper.Get(invoice);
}
///
/// Returns the pdf file associated with the invoice with the ID specified in the request
///
/// Invoice ID
/// Get invoice pdf file
/// Invoices
/// File
[Read(@"invoice/{invoiceid:int}/pdf")]
public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid)
{
if (invoiceid <= 0) throw new ArgumentException();
var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid);
if (invoice == null) throw new ItemNotFoundException();
if (!CRMSecurity.CanAccessTo(invoice))
{
throw CRMSecurity.CreateSecurityException();
}
return FileWrapperHelper.Get(GetInvoicePdfExistingOrCreate(invoice));
}
private ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice)
{
var existingFile = invoice.GetInvoiceFile(DaoFactory);
if (existingFile != null)
{
return existingFile;
}
else
{
var newFile = PdfCreator.CreateFile(invoice, DaoFactory);
invoice.FileID = Int32.Parse(newFile.ID.ToString());
DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID);
DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID });
return newFile;
}
}
///
/// Returns information about the generation of the pdf file of the invoice
///
/// Invoice ID
/// Storage Url
/// Revision ID
/// Check invoice pdf file
/// Invoices
/// ConverterData
[Create(@"invoice/converter/data")]
public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, string revisionId)
{
if (invoiceId <= 0) throw new ArgumentException();
var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId);
if (invoice == null) throw new ItemNotFoundException();
if (!CRMSecurity.CanAccessTo(invoice))
{
throw CRMSecurity.CreateSecurityException();
}
var converterData = new ConverterData
{
StorageUrl = storageUrl,
RevisionId = revisionId,
InvoiceId = invoiceId
};
var existingFile = invoice.GetInvoiceFile(DaoFactory);
if (existingFile != null)
{
converterData.FileId = invoice.FileID;
return converterData;
}
if (string.IsNullOrEmpty(storageUrl) || string.IsNullOrEmpty(revisionId))
{
return PdfCreator.StartCreationFileAsync(invoice);
}
else
{
var convertedFile = PdfCreator.GetConvertedFile(converterData, DaoFactory);
if (convertedFile != null)
{
invoice.FileID = Int32.Parse(convertedFile.ID.ToString());
DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID);
DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID });
converterData.FileId = invoice.FileID;
return converterData;
}
else
{
return converterData;
}
}
}
///
/// Returns the existence of the invoice with the Number specified in the request
///
/// Invoice number
/// Check invoice existence by number
/// Invoices
/// IsExist
[Read(@"invoice/bynumber/exist")]
public Boolean GetInvoiceByNumberExistence(string number)
{
if (String.IsNullOrEmpty(number)) throw new ArgumentException();
return DaoFactory.GetInvoiceDao().IsExist(number);
}
///
/// Returns the detailed information about the invoice with the Number specified in the request
///
/// Invoice number
/// Get invoice by number
/// Invoices
/// Invoice
[Read(@"invoice/bynumber")]
public InvoiceDto GetInvoiceByNumber(string number)
{
if (String.IsNullOrEmpty(number)) throw new ArgumentException();
var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number);
if (invoice == null) throw new ItemNotFoundException();
if (!CRMSecurity.CanAccessTo(invoice))
{
throw CRMSecurity.CreateSecurityException();
}
return InvoiceDtoHelper.Get(invoice);
}
///
/// Returns the list of invoice items matching the creteria specified in the request
///
/// Status
/// InventoryStock
/// Get invoice item list
/// Invoices
/// InvoiceItem list
[Read(@"invoiceitem/filter")]
public IEnumerable GetInvoiceItems(int status, bool? inventoryStock)
{
IEnumerable result;
InvoiceItemSortedByType sortBy;
OrderBy invoiceOrderBy;
var searchString = ApiContext.FilterValue;
if (InvoiceItemSortedByType.TryParse(ApiContext.SortBy, true, out sortBy))
{
invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending);
}
else if (String.IsNullOrEmpty(ApiContext.SortBy))
{
invoiceOrderBy = new OrderBy(InvoiceItemSortedByType.Name, true);
}
else
{
invoiceOrderBy = null;
}
var fromIndex = (int)ApiContext.StartIndex;
var count = (int)ApiContext.Count;
if (invoiceOrderBy != null)
{
result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems(
searchString,
status,
inventoryStock,
fromIndex, count,
invoiceOrderBy)
.ConvertAll(x => InvoiceItemDtoHelper.Get(x));
ApiContext.SetDataPaginated();
ApiContext.SetDataFiltered();
ApiContext.SetDataSorted();
}
else
{
result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems(
searchString,
status,
inventoryStock,
0, 0,
null)
.ConvertAll(x => InvoiceItemDtoHelper.Get(x));
}
int totalCount;
if (result.Count() < count)
{
totalCount = fromIndex + result.Count();
}
else
{
totalCount = DaoFactory.GetInvoiceItemDao().GetInvoiceItemsCount(
searchString,
status,
inventoryStock);
}
ApiContext.SetTotalCount(totalCount);
return result;
}
///
/// Returns the detailed information about the invoice item with the ID specified in the request
///
/// Invoice Item ID
/// Get invoice item by ID
/// Invoices
/// Invoice Item
[Read(@"invoiceitem/{invoiceitemid:int}")]
public InvoiceItemDto GetInvoiceItemByID(int invoiceitemid)
{
if (invoiceitemid <= 0) throw new ArgumentException();
var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid);
if (invoiceItem == null) throw new ItemNotFoundException();
return InvoiceItemDtoHelper.Get(invoiceItem);
}
///
/// Creates the invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request
///
/// Invoice ID
/// Invoice item ID
/// First invoice tax ID
/// Second invoice tax ID
/// Sort Order
/// Description
/// Quantity
/// Price
/// Discount
/// Create invoice line
/// Invoices
/// InvoiceLine
[Create(@"invoiceline")]
public InvoiceLineDto CreateInvoiceLine(
CreateOrUpdateInvoiceLineInDto inDto
)
{
int invoiceId = inDto.InvoiceId;
int invoiceItemId = inDto.InvoiceItemId;
int invoiceTax1Id = inDto.InvoiceTax1Id;
int invoiceTax2Id = inDto.InvoiceTax2Id;
int sortOrder = inDto.SortOrder;
string description = inDto.Description;
int quantity = inDto.Quantity;
decimal price = inDto.Price;
int discount = inDto.Discount;
var invoiceLine = new InvoiceLine
{
InvoiceID = invoiceId,
InvoiceItemID = invoiceItemId,
InvoiceTax1ID = invoiceTax1Id,
InvoiceTax2ID = invoiceTax2Id,
SortOrder = sortOrder,
Description = description,
Quantity = quantity,
Price = price,
Discount = discount
};
if (invoiceId <= 0)
throw new ArgumentException();
var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId);
CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice);
invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine);
DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice);
if (Global.CanDownloadInvoices)
{
// PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID);
}
return InvoiceLineDtoHelper.Get(invoiceLine);
}
///
/// Updates the selected invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request
///
/// Line ID
/// Invoice ID
/// Invoice item ID
/// First invoice tax ID
/// Second invoice tax ID
/// Sort Order
/// Description
/// Quantity
/// Price
/// Discount
/// Update invoice line
/// Invoices
/// InvoiceLine
[Update(@"invoiceline/{id:int}")]
public InvoiceLineDto UpdateInvoiceLine(
int id,
CreateOrUpdateInvoiceLineInDto inDto
)
{
int invoiceId = inDto.InvoiceId;
int invoiceItemId = inDto.InvoiceItemId;
int invoiceTax1Id = inDto.InvoiceTax1Id;
int invoiceTax2Id = inDto.InvoiceTax2Id;
int sortOrder = inDto.SortOrder;
string description = inDto.Description;
int quantity = inDto.Quantity;
decimal price = inDto.Price;
int discount = inDto.Discount;
if (invoiceId <= 0)
throw new ArgumentException();
var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id);
if (invoiceLine == null || invoiceLine.InvoiceID != invoiceId) throw new ItemNotFoundException();
invoiceLine.InvoiceID = invoiceId;
invoiceLine.InvoiceItemID = invoiceItemId;
invoiceLine.InvoiceTax1ID = invoiceTax1Id;
invoiceLine.InvoiceTax2ID = invoiceTax2Id;
invoiceLine.SortOrder = sortOrder;
invoiceLine.Description = description;
invoiceLine.Quantity = quantity;
invoiceLine.Price = price;
invoiceLine.Discount = discount;
var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId);
CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice);
DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine);
DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice);
if (Global.CanDownloadInvoices)
{
// PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID);
}
return InvoiceLineDtoHelper.Get(invoiceLine);
}
///
/// Deletes the invoice line with the ID specified in the request
///
/// Line ID
/// Delete invoice line
/// Invoices
/// Line ID
[Delete(@"invoiceline/{id:int}")]
public int DeleteInvoiceLine(int id)
{
var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id);
if (invoiceLine == null) throw new ItemNotFoundException();
if (!DaoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line");
var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID);
if (invoice == null) throw new ItemNotFoundException();
if (!CRMSecurity.CanEdit(invoice)) throw CRMSecurity.CreateSecurityException();
DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id);
DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice);
if (Global.CanDownloadInvoices)
{
// PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID);
}
return id;
}
///
/// Creates the invoice item with the parameters (title, description, price, etc.) specified in the request
///
/// Item title
/// Item description
/// Item price
/// Item stock keeping unit
/// Item quantity
/// Item stock quantity
/// Track inventory
/// Item first invoice tax ID
/// Item second invoice tax ID
/// Create invoice item
/// Invoices
/// InvoiceItem
[Create(@"invoiceitem")]
public InvoiceItemDto CreateInvoiceItem(
CreateOrUpdateInvoiceItemInDto inDto
)
{
string title = inDto.Title;
string description = inDto.Description;
decimal price = inDto.Price;
string sku = inDto.Sku;
int quantity = inDto.Quantity;
int stockQuantity = inDto.StockQuantity;
bool trackInventory = inDto.TrackInventory;
int invoiceTax1id = inDto.InvoiceTax1id;
int invoiceTax2id = inDto.InvoiceTax2id;
if (!CRMSecurity.IsAdmin)
{
throw CRMSecurity.CreateSecurityException();
}
if (String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException();
var invoiceItem = new InvoiceItem
{
Title = title,
Description = description,
Price = price,
StockKeepingUnit = sku,
StockQuantity = stockQuantity,
TrackInventory = trackInventory,
InvoiceTax1ID = invoiceTax1id,
InvoiceTax2ID = invoiceTax2id
};
invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem);
MessageService.Send(MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title);
return InvoiceItemDtoHelper.Get(invoiceItem);
}
///
/// Updates the selected invoice item with the parameters (title, description, price, etc.) specified in the request
///
/// Item ID
/// Item title
/// Item description
/// Item price
/// Item stock keeping unit
/// Item quantity
/// Item stock quantity
/// Track inventory
/// Item first invoice tax ID
/// Item second invoice tax ID
/// Update invoice item
/// Invoices
/// InvoiceItem
[Update(@"invoiceitem/{id:int}")]
public InvoiceItemDto UpdateInvoiceItem(int id,
CreateOrUpdateInvoiceItemInDto inDto
)
{
string title = inDto.Title;
string description = inDto.Description;
decimal price = inDto.Price;
string sku = inDto.Sku;
int quantity = inDto.Quantity;
int stockQuantity = inDto.StockQuantity;
bool trackInventory = inDto.TrackInventory;
int invoiceTax1id = inDto.InvoiceTax1id;
int invoiceTax2id = inDto.InvoiceTax2id;
if (!CRMSecurity.IsAdmin)
{
throw CRMSecurity.CreateSecurityException();
}
if (id <= 0 || String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException();
if (!DaoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException();
var invoiceItem = new InvoiceItem
{
ID = id,
Title = title,
Description = description,
Price = price,
StockKeepingUnit = sku,
StockQuantity = stockQuantity,
TrackInventory = trackInventory,
InvoiceTax1ID = invoiceTax1id,
InvoiceTax2ID = invoiceTax2id
};
invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem);
MessageService.Send(MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title);
return InvoiceItemDtoHelper.Get(invoiceItem);
}
///
/// Deletes the invoice item with the ID specified in the request
///
/// Item ID
/// Delete invoice item
/// Invoices
/// InvoiceItem
[Delete(@"invoiceitem/{id:int}")]
public InvoiceItemDto DeleteInvoiceItem(int id)
{
if (!CRMSecurity.IsAdmin)
{
throw CRMSecurity.CreateSecurityException();
}
if (id <= 0) throw new ArgumentException();
var invoiceItem = DaoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id);
if (invoiceItem == null) throw new ItemNotFoundException();
MessageService.Send(MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title);
return InvoiceItemDtoHelper.Get(invoiceItem);
}
///
/// Deletes the group of invoice items with the IDs specified in the request
///
/// Item ID list
/// Delete Invoice item group
/// Invoices
/// InvoiceItem list
[Delete(@"invoiceitem")]
public IEnumerable DeleteBatchItems(IEnumerable ids)
{
if (!CRMSecurity.IsAdmin)
{
throw CRMSecurity.CreateSecurityException();
}
if (ids == null) throw new ArgumentException();
ids = ids.Distinct();
var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray());
MessageService.Send(MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title));
return items.ConvertAll(x => InvoiceItemDtoHelper.Get(x));
}
///
/// Returns the list of invoice taxes
///
/// Get invoice taxes list
/// Invoices
/// InvoiceTax list
[Read(@"invoice/tax")]
public IEnumerable GetInvoiceTaxes()
{
return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxDtoHelper.Get(x));
}
///
/// Creates the invoice tax with the parameters (name, description, rate) specified in the request
///
/// Tax name
/// Tax description
/// Tax rate
/// Create invoice tax
/// Invoices
/// InvoiceTax
[Create(@"invoice/tax")]
public InvoiceTaxDto CreateInvoiceTax(
[FromBody] CreateOrUpdateInvoiceTax inDto)
{
string name = inDto.Name;
string description = inDto.Description;
decimal rate = inDto.Rate;
if (!CRMSecurity.IsAdmin)
{
throw CRMSecurity.CreateSecurityException();
}
if (String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError);
if (DaoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError);
var invoiceTax = new InvoiceTax
{
Name = name,
Description = description,
Rate = rate
};
invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax);
MessageService.Send(MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name);
return InvoiceTaxDtoHelper.Get(invoiceTax);
}
///
/// Updates the selected invoice tax with the parameters (name, description, rate) specified in the request
///
/// Tax ID
/// Tax name
/// Tax description
/// Tax rate
/// Update invoice tax
/// Invoices
/// InvoiceTax
[Update(@"invoice/tax/{id:int}")]
public InvoiceTaxDto UpdateInvoiceTax(
int id,
CreateOrUpdateInvoiceTax inDto)
{
string name = inDto.Name;
string description = inDto.Description;
decimal rate = inDto.Rate;
if (!CRMSecurity.IsAdmin)
{
throw CRMSecurity.CreateSecurityException();
}
if (id <= 0 || String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError);
if (!DaoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException();
var invoiceTax = new InvoiceTax
{
ID = id,
Name = name,
Description = description,
Rate = rate
};
invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax);
MessageService.Send(MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name);
return InvoiceTaxDtoHelper.Get(invoiceTax);
}
///
/// Delete the invoice tax with the ID specified in the request
///
/// Tax ID
/// Delete invoice tax
/// Invoices
/// InvoiceTax
[Delete(@"invoice/tax/{id:int}")]
public InvoiceTaxDto DeleteInvoiceTax(int id)
{
if (!CRMSecurity.IsAdmin)
{
throw CRMSecurity.CreateSecurityException();
}
if (id <= 0) throw new ArgumentException();
var invoiceTax = DaoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id);
if (invoiceTax == null) throw new ItemNotFoundException();
MessageService.Send(MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name);
return InvoiceTaxDtoHelper.Get(invoiceTax);
}
///
/// Get default invoice settings
///
/// Get default invoice settings
/// Invoices
/// InvoiceSetting
[Read(@"invoice/settings")]
public InvoiceSetting GetSettings()
{
return DaoFactory.GetInvoiceDao().GetSettings();
}
///
/// Save default invoice number
///
/// Is autogenerated
/// Prefix
/// Number
/// Save default invoice number
/// Invoices
/// InvoiceSetting
[Update(@"invoice/settings/name")]
public InvoiceSetting SaveNumberSettings(
SaveNumberSettingsInDto inDto
)
{
var autogenerated = inDto.AutoGenerated;
var number = inDto.Number;
var prefix = inDto.Prefix;
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
if (autogenerated && string.IsNullOrEmpty(number))
throw new ArgumentException();
if (autogenerated && DaoFactory.GetInvoiceDao().IsExist(prefix + number))
throw new ArgumentException();
var invoiceSetting = GetSettings();
invoiceSetting.Autogenerated = autogenerated;
invoiceSetting.Prefix = prefix;
invoiceSetting.Number = number;
var settings = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting);
MessageService.Send(MessageAction.InvoiceNumberFormatUpdated);
return settings;
}
///
/// Save default invoice terms
///
/// Terms
/// Save default invoice terms
/// Invoices
/// InvoiceSetting
[Update(@"invoice/settings/terms")]
public InvoiceSetting SaveTermsSettings(string terms)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var invoiceSetting = GetSettings();
invoiceSetting.Terms = terms;
var result = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting);
MessageService.Send(MessageAction.InvoiceDefaultTermsUpdated);
return result;
}
/// false
[Update(@"invoice/{invoiceid:int}/creationdate")]
public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate)
{
var dao = DaoFactory.GetInvoiceDao();
var invoice = dao.GetByID(invoiceid);
if (invoice == null || !CRMSecurity.CanAccessTo(invoice))
throw new ItemNotFoundException();
dao.SetInvoiceCreationDate(invoiceid, creationDate);
}
/// false
[Update(@"invoice/{invoiceid:int}/lastmodifeddate")]
public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate)
{
var dao = DaoFactory.GetInvoiceDao();
var invoice = dao.GetByID(invoiceid);
if (invoice == null || !CRMSecurity.CanAccessTo(invoice))
throw new ItemNotFoundException();
dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate);
}
private IEnumerable ToListInvoiceBaseDtos(ICollection items)
{
if (items == null || items.Count == 0) return new List();
var result = new List();
var contactIDs = items.Select(item => item.ContactID);
contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID));
var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray())
.ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseWithEmailDto(x));
foreach (var invoice in items)
{
var invoiceDto = InvoiceBaseDtoHelper.Get(invoice);
if (contacts.ContainsKey(invoice.ContactID))
{
invoiceDto.Contact = contacts[invoice.ContactID];
}
if (contacts.ContainsKey(invoice.ConsigneeID))
{
invoiceDto.Consignee = contacts[invoice.ContactID];
}
if (invoice.EntityID > 0)
{
invoiceDto.Entity = ToEntityDto(invoice.EntityType, invoice.EntityID); //Need to optimize
}
invoiceDto.Cost = invoice.GetInvoiceCost(DaoFactory);
result.Add(invoiceDto);
}
return result;
}
}
}