diff --git a/source/XeroApi/AttachmentRepository.cs b/source/XeroApi/AttachmentRepository.cs
index 089e2a9..04336a6 100644
--- a/source/XeroApi/AttachmentRepository.cs
+++ b/source/XeroApi/AttachmentRepository.cs
@@ -2,94 +2,114 @@
using System.Linq;
using XeroApi.Integration;
using XeroApi.Model;
-using XeroApi.Model.Serialize;
+
namespace XeroApi
{
public class AttachmentRepository
{
private readonly IIntegrationProxy _integrationProxy;
- private readonly IModelSerializer _serializer;
+
///
/// Initializes a new instance of the class.
///
/// The integration proxy.
- ///
- internal AttachmentRepository(IIntegrationProxy integrationProxy, IModelSerializer serializer)
+ internal AttachmentRepository(IIntegrationProxy integrationProxy)
{
_integrationProxy = integrationProxy;
- _serializer = serializer;
}
+
+
+
// POST
+
public Attachment UpdateOrCreate(TModel model, FileInfo fileInfo)
where TModel : ModelBase, IAttachmentParent
{
return UpdateOrCreate(model, new Attachment(fileInfo));
}
+
public Attachment UpdateOrCreate(TModel model, Attachment attachment)
where TModel : ModelBase, IAttachmentParent
{
- string data = _integrationProxy.UpdateOrCreateAttachment(
+ string xml = _integrationProxy.UpdateOrCreateAttachment(
typeof(TModel).Name,
ModelTypeHelper.GetModelItemId(model),
attachment);
- var response = _serializer.DeserializeTo(data);
+
+ Response response = ModelSerializer.DeserializeTo(xml);
+
return response.Attachments.First();
}
+
+
// PUT
+
public Attachment Create(TModel model, FileInfo fileInfo)
where TModel : ModelBase, IAttachmentParent
{
return Create(model, new Attachment(fileInfo));
}
+
public Attachment Create(TModel model, Attachment attachment)
where TModel : ModelBase, IAttachmentParent
{
- string data = _integrationProxy.CreateAttachment(
+ string xml = _integrationProxy.CreateAttachment(
typeof(TModel).Name,
ModelTypeHelper.GetModelItemId(model),
attachment);
- return _serializer.DeserializeTo(data).Attachments.First();
+
+ return ModelSerializer.DeserializeTo(xml).Attachments.First();
}
+
+
// GET (one)
+
public Attachment GetAttachmentFor(TModel model)
where TModel : ModelBase, IAttachmentParent
{
// List the attachments against this model.
var modelItemId = ModelTypeHelper.GetModelItemId(model);
+
var allAttachmentsXml = _integrationProxy.FindAttachments(typeof(TModel).Name, modelItemId);
- var allAttachments = _serializer.DeserializeTo(allAttachmentsXml).Attachments;
+
+ var allAttachments = ModelSerializer.DeserializeTo(allAttachmentsXml).Attachments;
+
if (allAttachments == null || allAttachments.Count == 0)
{
return null;
}
+
var theFirstAttachment = allAttachments.First();
+
// Get the attachment content
var content = _integrationProxy.FindOneAttachment(
- typeof (TModel).Name,
+ typeof(TModel).Name,
modelItemId,
- theFirstAttachment.AttachmentID.ToString());
+ theFirstAttachment.FileName);
+
return theFirstAttachment.WithContent(content);
}
}
+
}
diff --git a/source/XeroApi/CoreRepository.cs b/source/XeroApi/CoreRepository.cs
index 9fd9773..715595b 100644
--- a/source/XeroApi/CoreRepository.cs
+++ b/source/XeroApi/CoreRepository.cs
@@ -118,7 +118,7 @@ public IQueryable ExpenseClaims
public AttachmentRepository Attachments
{
- get { return new AttachmentRepository(Proxy, Serializer); }
+ get { return new AttachmentRepository(Proxy); }
}
public ReportRepository Reports
diff --git a/source/XeroApi/Linq/ApiQueryTranslator.cs b/source/XeroApi/Linq/ApiQueryTranslator.cs
index af9775c..82217d3 100644
--- a/source/XeroApi/Linq/ApiQueryTranslator.cs
+++ b/source/XeroApi/Linq/ApiQueryTranslator.cs
@@ -1,99 +1,99 @@
using System;
using System.Collections;
-using System.Linq;
-using System.Linq.Expressions;
-
-namespace XeroApi.Linq
-{
- ///
- /// Translates a linq query into a .
- ///
- internal class ApiQueryTranslator : ExpressionVisitor
- {
- private LinqQueryDescription _query;
- private ApiQuerystringName _currentQueryStringName = ApiQuerystringName.Unknown;
-
-
- ///
- /// Translates the specified linq expression into a .
- ///
- /// The linq expression.
- ///
- internal LinqQueryDescription Translate(Expression expression)
- {
- _query = new LinqQueryDescription();
-
- if (expression.Type.IsGenericType)
- {
- _query.ElementType = expression.Type.GetGenericArguments()[0];
- }
-
- Visit(expression);
-
- return _query;
- }
-
- protected override Expression VisitMethodCall(MethodCallExpression m)
- {
- switch (m.Method.Name)
- {
- case "Where":
-
- using (new QuerystringScope(this, ApiQuerystringName.Where))
- {
- return base.VisitMethodCall(m);
- }
-
- case "FirstOrDefault":
- case "First":
- case "SingleOrDefault":
- case "Single":
-
- if (!string.IsNullOrEmpty(_query.ClientSideExpression) && !_query.ClientSideExpression.Equals(m.Method.Name))
- {
- throw new NotImplementedException("Only 1 aggregator expression can currently be performed.");
- }
-
- _query.ClientSideExpression = m.Method.Name;
-
- using (new QuerystringScope(this, ApiQuerystringName.Where))
- {
- return base.VisitMethodCall(m);
- }
-
- case "Count":
-
- if (!string.IsNullOrEmpty(_query.ClientSideExpression) && !_query.ClientSideExpression.Equals(m.Method.Name))
- {
- throw new NotImplementedException("Only 1 aggregator expression can currently be performed.");
- }
-
- _query.ClientSideExpression = m.Method.Name;
- return base.VisitMethodCall(m);
-
- case "OrderBy":
- case "ThenBy":
-
- using (new QuerystringScope(this, ApiQuerystringName.OrderBy))
- {
- return base.VisitMethodCall(m);
- }
-
- case "OrderByDescending":
- case "ThenByDescending":
-
- using (new QuerystringScope(this, ApiQuerystringName.OrderBy))
- {
- var expression = base.VisitMethodCall(m);
- Append(" DESC");
- return expression;
- }
-
- case "Skip":
- using (new QuerystringScope(this, ApiQuerystringName.Skip))
- {
- return base.VisitMethodCall(m);
- }
+using System.Linq;
+using System.Linq.Expressions;
+
+namespace XeroApi.Linq
+{
+ ///
+ /// Translates a linq query into a .
+ ///
+ internal class ApiQueryTranslator : ExpressionVisitor
+ {
+ private LinqQueryDescription _query;
+ private ApiQuerystringName _currentQueryStringName = ApiQuerystringName.Unknown;
+
+
+ ///
+ /// Translates the specified linq expression into a .
+ ///
+ /// The linq expression.
+ ///
+ internal LinqQueryDescription Translate(Expression expression)
+ {
+ _query = new LinqQueryDescription();
+
+ if (expression.Type.IsGenericType)
+ {
+ _query.ElementType = expression.Type.GetGenericArguments()[0];
+ }
+
+ Visit(expression);
+
+ return _query;
+ }
+
+ protected override Expression VisitMethodCall(MethodCallExpression m)
+ {
+ switch (m.Method.Name)
+ {
+ case "Where":
+
+ using (new QuerystringScope(this, ApiQuerystringName.Where))
+ {
+ return base.VisitMethodCall(m);
+ }
+
+ case "FirstOrDefault":
+ case "First":
+ case "SingleOrDefault":
+ case "Single":
+
+ if (!string.IsNullOrEmpty(_query.ClientSideExpression) && !_query.ClientSideExpression.Equals(m.Method.Name))
+ {
+ throw new NotImplementedException("Only 1 aggregator expression can currently be performed.");
+ }
+
+ _query.ClientSideExpression = m.Method.Name;
+
+ using (new QuerystringScope(this, ApiQuerystringName.Where))
+ {
+ return base.VisitMethodCall(m);
+ }
+
+ case "Count":
+
+ if (!string.IsNullOrEmpty(_query.ClientSideExpression) && !_query.ClientSideExpression.Equals(m.Method.Name))
+ {
+ throw new NotImplementedException("Only 1 aggregator expression can currently be performed.");
+ }
+
+ _query.ClientSideExpression = m.Method.Name;
+ return base.VisitMethodCall(m);
+
+ case "OrderBy":
+ case "ThenBy":
+
+ using (new QuerystringScope(this, ApiQuerystringName.OrderBy))
+ {
+ return base.VisitMethodCall(m);
+ }
+
+ case "OrderByDescending":
+ case "ThenByDescending":
+
+ using (new QuerystringScope(this, ApiQuerystringName.OrderBy))
+ {
+ var expression = base.VisitMethodCall(m);
+ Append(" DESC");
+ return expression;
+ }
+
+ case "Skip":
+ using (new QuerystringScope(this, ApiQuerystringName.Skip))
+ {
+ return base.VisitMethodCall(m);
+ }
}
var rootExpressionType = FindRootExpressionType(m);
@@ -107,8 +107,8 @@ protected override Expression VisitMethodCall(MethodCallExpression m)
case ExpressionType.Parameter:
Append(ParseExpression(m));
return m;
- }
-
+ }
+
// If this is a method from a clr object, as opposed to an extension method, the API server just might be able to support it.
if (m.Method.DeclaringType == typeof(string) ||
m.Method.DeclaringType == typeof(DateTime) ||
@@ -116,50 +116,50 @@ protected override Expression VisitMethodCall(MethodCallExpression m)
{
return VisitObjectMethodCall(m);
}
-
- throw new NotImplementedException(string.Format("The method '{0}' can't currently be used in a XeroApi WHERE querystring.", m.Method.Name));
- }
-
-
- protected Expression VisitObjectMethodCall(MethodCallExpression m)
- {
- // The .Contains and .StartsWith methods on string objects are supported by the API server
- // e.g.
- // c => c.Name.StartsWith("Jason")
- // c => c.Name.Contains("ase")
-
- if (m.Method.IsStatic && m.Method.DeclaringType != null)
- {
- Append(m.Method.DeclaringType.Name);
- }
-
- Expression obj = Visit(m.Object);
-
- Append(".");
- Append(m.Method.Name);
- Append("(");
- var args = VisitExpressionList(m.Arguments);
- Append(")");
-
- return UpdateMethodCall(m, obj, m.Method, args);
- }
-
-
- protected override Expression VisitUnary(UnaryExpression u)
- {
- switch (u.NodeType)
- {
- case ExpressionType.Not:
- Append("(");
- Visit(u.Operand);
- Append(" == false)");
- break;
- default:
- Visit(u.Operand);
- break;
- }
-
- return u;
+
+ throw new NotImplementedException(string.Format("The method '{0}' can't currently be used in a XeroApi WHERE querystring.", m.Method.Name));
+ }
+
+
+ protected Expression VisitObjectMethodCall(MethodCallExpression m)
+ {
+ // The .Contains and .StartsWith methods on string objects are supported by the API server
+ // e.g.
+ // c => c.Name.StartsWith("Jason")
+ // c => c.Name.Contains("ase")
+
+ if (m.Method.IsStatic && m.Method.DeclaringType != null)
+ {
+ Append(m.Method.DeclaringType.Name);
+ }
+
+ Expression obj = Visit(m.Object);
+
+ Append(".");
+ Append(m.Method.Name);
+ Append("(");
+ var args = VisitExpressionList(m.Arguments);
+ Append(")");
+
+ return UpdateMethodCall(m, obj, m.Method, args);
+ }
+
+
+ protected override Expression VisitUnary(UnaryExpression u)
+ {
+ switch (u.NodeType)
+ {
+ case ExpressionType.Not:
+ Append("(");
+ Visit(u.Operand);
+ Append(" == false)");
+ break;
+ default:
+ Visit(u.Operand);
+ break;
+ }
+
+ return u;
}
@@ -178,75 +178,75 @@ protected override Expression VisitLambda(LambdaExpression lambda)
}
return base.VisitLambda(lambda);
- }
-
-
- ///
- /// Determines whether the expression is to be rendered into the WHERE or ORDER clause
- ///
- /// The expression.
- ///
- /// true if [is not rendered into expression] [the specified expression]; otherwise, false.
- ///
- private bool IsNotRenderedIntoExpression(Expression expression)
- {
- var binaryExpression = expression as BinaryExpression;
-
- if (binaryExpression == null)
- return false;
-
- var mExp = binaryExpression.Left as MemberExpression;
-
- // Check if the LHS is an ItemId, ItemNumber or UpdatedDate. If so, record away from the main where clause.
- if (mExp != null && mExp.Member.DeclaringType != null && mExp.Member.DeclaringType.Name == _query.ElementName)
- {
- if (mExp.Member.Name == _query.ElementIdProperty.SafeName()
- || mExp.Member.Name == _query.ElementNumberProperty.SafeName()
- || mExp.Member.Name == _query.ElementUpdatedDateProperty.SafeName())
- {
- return true;
- }
- }
-
- return false;
- }
-
-
- protected override Expression VisitBinary(BinaryExpression b)
- {
- var mExp = b.Left as MemberExpression;
-
- // Check if the LHS is an ItemId, ItemNumber or UpdatedDate. If so, record away from the main where clause.
- if (mExp != null && mExp.Member.DeclaringType != null && mExp.Member.DeclaringType.Name == _query.ElementName)
- {
- if (mExp.Member.Name == _query.ElementIdProperty.SafeName())
- {
- if (b.Right.Type == typeof (Guid?))
- _query.ElementId = EvaluateExpression(b.Right).ToString();
- else if (b.Right.Type == typeof (Guid))
- _query.ElementId = EvaluateExpression(b.Right).ToString();
- return b;
- }
- if (mExp.Member.Name == _query.ElementNumberProperty.SafeName())
- {
- var rightValue = EvaluateExpression