diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bc9a86a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+*/bin/*
+packages/
+bin/
+*.suo
+desktop.ini
+*.user
+**/obj/*
+*.mdf
+*.ldf
diff --git a/CQRS.Base/CQRS.Base.csproj b/CQRS.Base/CQRS.Base.csproj
new file mode 100644
index 0000000..b908830
--- /dev/null
+++ b/CQRS.Base/CQRS.Base.csproj
@@ -0,0 +1,74 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}
+ Library
+ Properties
+ CQRS.Base
+ CQRS.Base
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll
+ True
+
+
+ ..\packages\NHibernate.4.0.4.4000\lib\net40\NHibernate.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {2230C68D-558A-463F-B3ED-427968DECB2E}
+ PhotoStock.Sales.Domain
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CQRS.Base/Command/ICommandHandler.cs b/CQRS.Base/Command/ICommandHandler.cs
new file mode 100644
index 0000000..626cae3
--- /dev/null
+++ b/CQRS.Base/Command/ICommandHandler.cs
@@ -0,0 +1,7 @@
+namespace CQRS.Base.Command
+{
+ public interface ICommandHandler
+ {
+ void Handle(TCommand command);
+ }
+}
\ No newline at end of file
diff --git a/CQRS.Base/Command/ICommandSender.cs b/CQRS.Base/Command/ICommandSender.cs
new file mode 100644
index 0000000..12e33ae
--- /dev/null
+++ b/CQRS.Base/Command/ICommandSender.cs
@@ -0,0 +1,7 @@
+namespace CQRS.Base.Command
+{
+ public interface ICommandSender
+ {
+ void Send(TCommand command);
+ }
+}
\ No newline at end of file
diff --git a/CQRS.Base/Events/IEventListener.cs b/CQRS.Base/Events/IEventListener.cs
new file mode 100644
index 0000000..6f17241
--- /dev/null
+++ b/CQRS.Base/Events/IEventListener.cs
@@ -0,0 +1,7 @@
+namespace CQRS.Base.Events
+{
+ public interface IEventListener
+ {
+ void Handle(TEvent eventData);
+ }
+}
\ No newline at end of file
diff --git a/CQRS.Base/Properties/AssemblyInfo.cs b/CQRS.Base/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..bad425b
--- /dev/null
+++ b/CQRS.Base/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CQRS.Base")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CQRS.Base")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7d8d2feb-c2e5-4d54-8369-21de2d44984a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/CQRS.Base/Query/PaginatedResult.cs b/CQRS.Base/Query/PaginatedResult.cs
new file mode 100644
index 0000000..204bbf3
--- /dev/null
+++ b/CQRS.Base/Query/PaginatedResult.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace CQRS.Base.Query
+{
+ public class PaginatedResult
+ {
+ public List Items { get; private set; }
+ public int PageSize { get; private set; }
+ public int PageNumber { get; private set; }
+ public int PagesCount { get; private set; }
+ public int TotalItemsCount { get; private set; }
+
+ public PaginatedResult(int pageNumber, int pageSize)
+ {
+ PageNumber = pageNumber;
+ PageSize = pageSize;
+ Items = new List();
+ PagesCount = 0;
+ TotalItemsCount = 0;
+ }
+
+ public PaginatedResult(List items, int pageNumber, int pageSize, int totalItemsCount)
+ {
+ Items = items;
+ PageNumber = pageNumber;
+ PageSize = pageSize;
+ PagesCount = CountPages(pageSize, totalItemsCount);
+ TotalItemsCount = totalItemsCount;
+ }
+
+ private int CountPages(int size, int itemsCount)
+ {
+ return (int)Math.Ceiling((double)itemsCount / size);
+ }
+ }
+}
\ No newline at end of file
diff --git a/CQRS.Base/packages.config b/CQRS.Base/packages.config
new file mode 100644
index 0000000..30a8e96
--- /dev/null
+++ b/CQRS.Base/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/DDD.Base/DDD.Base.csproj b/DDD.Base/DDD.Base.csproj
new file mode 100644
index 0000000..3750f6a
--- /dev/null
+++ b/DDD.Base/DDD.Base.csproj
@@ -0,0 +1,71 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ Library
+ Properties
+ DDD.Base
+ DDD.Base
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DDD.Base/Domain/AggregateRoot.cs b/DDD.Base/Domain/AggregateRoot.cs
new file mode 100644
index 0000000..b69d375
--- /dev/null
+++ b/DDD.Base/Domain/AggregateRoot.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace DDD.Base.Domain
+{
+ public abstract class AggregateRoot
+ {
+ public enum AggregateStatus
+ {
+ ACTIVE, ARCHIVE
+ }
+
+ public AggregateId AggregateId { get; private set; }
+
+ public int Version { get; private set; }
+ private AggregateStatus _aggregateStatus = AggregateStatus.ACTIVE;
+
+ protected IDomainEventPublisher EventPublisher { get; private set; }
+
+ protected AggregateRoot()
+ {
+ Version = 0;
+ }
+
+ public AggregateRoot(AggregateId aggregateId)
+ {
+ AggregateId = aggregateId;
+ }
+
+ public void MarkAsRemoved()
+ {
+ _aggregateStatus = AggregateStatus.ARCHIVE;
+ }
+
+ public bool IsRemoved()
+ {
+ return _aggregateStatus == AggregateStatus.ARCHIVE;
+ }
+
+ protected void DomainError(string message)
+ {
+ throw new DomainOperationException(AggregateId, message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/AgregateId.cs b/DDD.Base/Domain/AgregateId.cs
new file mode 100644
index 0000000..8444a62
--- /dev/null
+++ b/DDD.Base/Domain/AgregateId.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+
+namespace DDD.Base.Domain
+{
+ public class AggregateId : ValueObject
+ {
+ private string _innerId;
+
+ public AggregateId(string value)
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ _innerId = value;
+ }
+
+ protected AggregateId()
+ {
+ }
+
+ public static AggregateId Generate()
+ {
+ return new AggregateId(Guid.NewGuid().ToString());
+ }
+
+ public static implicit operator AggregateId(string value)
+ {
+ return new AggregateId(value);
+ }
+
+ public static implicit operator string(AggregateId aggregateId)
+ {
+ if (aggregateId != null)
+ {
+ return aggregateId._innerId;
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/DomainOperationException.cs b/DDD.Base/Domain/DomainOperationException.cs
new file mode 100644
index 0000000..e5cb39e
--- /dev/null
+++ b/DDD.Base/Domain/DomainOperationException.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace DDD.Base.Domain
+{
+ public class DomainOperationException : Exception
+ {
+ public AggregateId AggregateId { get; set; }
+
+ public DomainOperationException(AggregateId aggregateId, string message) : base(message)
+ {
+ AggregateId = aggregateId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/Entity.cs b/DDD.Base/Domain/Entity.cs
new file mode 100644
index 0000000..2d8de1a
--- /dev/null
+++ b/DDD.Base/Domain/Entity.cs
@@ -0,0 +1,7 @@
+namespace DDD.Base.Domain
+{
+ public abstract class Entity
+ {
+ public int Id { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/Exceptions/IllegalStateException.cs b/DDD.Base/Domain/Exceptions/IllegalStateException.cs
new file mode 100644
index 0000000..a0e9eda
--- /dev/null
+++ b/DDD.Base/Domain/Exceptions/IllegalStateException.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace DDD.Base.Domain.Exceptions
+{
+ public class IllegalStateException : Exception
+ {
+ public IllegalStateException(string message) : base(message)
+ {
+ }
+
+ public IllegalStateException()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/IDependencyInjector.cs b/DDD.Base/Domain/IDependencyInjector.cs
new file mode 100644
index 0000000..74a5317
--- /dev/null
+++ b/DDD.Base/Domain/IDependencyInjector.cs
@@ -0,0 +1,7 @@
+namespace DDD.Base.Domain
+{
+ public interface IDependencyInjector
+ {
+ void InjectDependencies(AggregateRoot aggregateRoot);
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/IDomainEvent.cs b/DDD.Base/Domain/IDomainEvent.cs
new file mode 100644
index 0000000..0b459ef
--- /dev/null
+++ b/DDD.Base/Domain/IDomainEvent.cs
@@ -0,0 +1,8 @@
+namespace DDD.Base.Domain
+{
+ // Remove marker interface
+ //[Domain@event]
+ public interface IDomainEvent
+ {
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/IDomainEventPublisher.cs b/DDD.Base/Domain/IDomainEventPublisher.cs
new file mode 100644
index 0000000..037c93f
--- /dev/null
+++ b/DDD.Base/Domain/IDomainEventPublisher.cs
@@ -0,0 +1,7 @@
+namespace DDD.Base.Domain
+{
+ public interface IDomainEventPublisher
+ {
+ void Publish(T domainEvent) where T : IDomainEvent;
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/IGenericRepository.cs b/DDD.Base/Domain/IGenericRepository.cs
new file mode 100644
index 0000000..378c39a
--- /dev/null
+++ b/DDD.Base/Domain/IGenericRepository.cs
@@ -0,0 +1,13 @@
+using System.Collections;
+
+namespace DDD.Base.Domain
+{
+ public interface IGenericRepository where T : AggregateRoot
+ {
+ T Load(AggregateId id);
+
+ void Delete(AggregateId id);
+
+ void Save(T entity);
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Domain/ValueObject.cs b/DDD.Base/Domain/ValueObject.cs
new file mode 100644
index 0000000..e8bd365
--- /dev/null
+++ b/DDD.Base/Domain/ValueObject.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace DDD.Base.Domain
+{
+ public abstract class ValueObject : IEqualityComparer, IEquatable
+ {
+ private const int Multiplier = 59;
+ private const int StartValue = 17;
+
+ public static bool operator ==(ValueObject x, ValueObject y)
+ {
+ if (ReferenceEquals(x, null) && ReferenceEquals(y, null))
+ {
+ return true;
+ }
+
+ if (ReferenceEquals(x, null))
+ {
+ return false;
+ }
+
+ return x.Equals(y);
+ }
+
+ public static bool operator !=(ValueObject x, ValueObject y)
+ {
+ return !(x == y);
+ }
+
+ public virtual bool Equals(ValueObject other)
+ {
+ if (other == null)
+ {
+ return false;
+ }
+
+ Type t = GetType();
+
+ Type otherType = other.GetType();
+
+ if (t != otherType)
+ {
+ return false;
+ }
+
+ FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
+
+ foreach (FieldInfo field in fields)
+ {
+ object value1 = field.GetValue(other);
+
+ object value2 = field.GetValue(this);
+
+ if (value1 == null)
+ {
+ if (value2 != null)
+ {
+ return false;
+ }
+ }
+ else if (!value1.Equals(value2))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ var other = obj as ValueObject;
+
+ return Equals(other);
+ }
+
+ public override int GetHashCode()
+ {
+ IEnumerable fields = GetFields();
+
+ int startValue = StartValue;
+
+ int multiplier = Multiplier;
+
+ int hashCode = startValue;
+
+ foreach (FieldInfo field in fields)
+ {
+ object value = field.GetValue(this);
+
+ if (value != null)
+ {
+ hashCode = (hashCode * multiplier) + value.GetHashCode();
+ }
+ }
+
+ return hashCode;
+ }
+
+ private IEnumerable GetFields()
+ {
+ Type t = GetType();
+
+ var fields = new List();
+
+ while (t != typeof(object))
+ {
+ fields.AddRange(t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
+
+ t = t.BaseType;
+ }
+
+ return fields;
+ }
+
+ public bool Equals(object x, object y)
+ {
+ if (ReferenceEquals(x, null) && ReferenceEquals(y, null))
+ {
+ return true;
+ }
+
+ if (ReferenceEquals(x, null))
+ {
+ return false;
+ }
+
+ return x.Equals(y);
+ }
+
+ public int GetHashCode(object obj)
+ {
+ return obj.GetHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/Properties/AssemblyInfo.cs b/DDD.Base/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1e198a2
--- /dev/null
+++ b/DDD.Base/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DDD.Base")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DDD.Base")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f8d43559-8792-498b-ab51-211ca04cb4df")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/DDD.Base/Sagas/ISagaManager.cs b/DDD.Base/Sagas/ISagaManager.cs
new file mode 100644
index 0000000..8e61c56
--- /dev/null
+++ b/DDD.Base/Sagas/ISagaManager.cs
@@ -0,0 +1,7 @@
+namespace DDD.Base.Sagas
+{
+ public interface ISagaManager
+ {
+ void ProcessMessage(T message);
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/SharedKernel/Specification/AndSpecification.cs b/DDD.Base/SharedKernel/Specification/AndSpecification.cs
new file mode 100644
index 0000000..ae598d1
--- /dev/null
+++ b/DDD.Base/SharedKernel/Specification/AndSpecification.cs
@@ -0,0 +1,19 @@
+namespace DDD.Base.SharedKernel.Specification
+{
+ public class AndSpecification : CompositeSpecification
+ {
+ private ISpecification _a;
+ private ISpecification _b;
+
+ public AndSpecification(ISpecification a, ISpecification b)
+ {
+ _a = a;
+ _b = b;
+ }
+
+ public override bool IsSatisfiedBy(T offer)
+ {
+ return _a.IsSatisfiedBy(offer) && _b.IsSatisfiedBy(offer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/SharedKernel/Specification/CompositeSpecification.cs b/DDD.Base/SharedKernel/Specification/CompositeSpecification.cs
new file mode 100644
index 0000000..6d3dee1
--- /dev/null
+++ b/DDD.Base/SharedKernel/Specification/CompositeSpecification.cs
@@ -0,0 +1,22 @@
+namespace DDD.Base.SharedKernel.Specification
+{
+ public abstract class CompositeSpecification : ISpecification
+ {
+ public abstract bool IsSatisfiedBy(T offer);
+
+ public ISpecification And(ISpecification other)
+ {
+ return new AndSpecification(this, other);
+ }
+
+ public ISpecification Or(ISpecification other)
+ {
+ return new OrSpecification(this, other);
+ }
+
+ public ISpecification Not()
+ {
+ return new NotSpecification(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/SharedKernel/Specification/ConjunctionSpecification.cs b/DDD.Base/SharedKernel/Specification/ConjunctionSpecification.cs
new file mode 100644
index 0000000..423b498
--- /dev/null
+++ b/DDD.Base/SharedKernel/Specification/ConjunctionSpecification.cs
@@ -0,0 +1,19 @@
+using System.Linq;
+
+namespace DDD.Base.SharedKernel.Specification
+{
+ public class ConjunctionSpecification : CompositeSpecification
+ {
+ private readonly ISpecification[] _conjunction;
+
+ public ConjunctionSpecification(params ISpecification[] conjunction)
+ {
+ _conjunction = conjunction;
+ }
+
+ public override bool IsSatisfiedBy(T offer)
+ {
+ return _conjunction.All(spec => spec.IsSatisfiedBy(offer));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/SharedKernel/Specification/DisjunctionSpecification.cs b/DDD.Base/SharedKernel/Specification/DisjunctionSpecification.cs
new file mode 100644
index 0000000..6d77336
--- /dev/null
+++ b/DDD.Base/SharedKernel/Specification/DisjunctionSpecification.cs
@@ -0,0 +1,19 @@
+using System.Linq;
+
+namespace DDD.Base.SharedKernel.Specification
+{
+ public class DisjunctionSpecification : CompositeSpecification
+ {
+ private readonly ISpecification[] _disjunction;
+
+ public DisjunctionSpecification(ISpecification[] disjunction)
+ {
+ _disjunction = disjunction;
+ }
+
+ public override bool IsSatisfiedBy(T offer)
+ {
+ return _disjunction.Any(spec => spec.IsSatisfiedBy(offer));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/SharedKernel/Specification/ISpecification.cs b/DDD.Base/SharedKernel/Specification/ISpecification.cs
new file mode 100644
index 0000000..02bdfd2
--- /dev/null
+++ b/DDD.Base/SharedKernel/Specification/ISpecification.cs
@@ -0,0 +1,13 @@
+namespace DDD.Base.SharedKernel.Specification
+{
+ public interface ISpecification
+ {
+ bool IsSatisfiedBy(T offer);
+
+ ISpecification And(ISpecification other);
+
+ ISpecification Or(ISpecification other);
+
+ ISpecification Not();
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/SharedKernel/Specification/NotSpecification.cs b/DDD.Base/SharedKernel/Specification/NotSpecification.cs
new file mode 100644
index 0000000..03c7b37
--- /dev/null
+++ b/DDD.Base/SharedKernel/Specification/NotSpecification.cs
@@ -0,0 +1,17 @@
+namespace DDD.Base.SharedKernel.Specification
+{
+ public class NotSpecification : CompositeSpecification
+ {
+ private ISpecification _wrapped;
+
+ public NotSpecification(ISpecification wrapped)
+ {
+ _wrapped = wrapped;
+ }
+
+ public override bool IsSatisfiedBy(T offer)
+ {
+ return !_wrapped.IsSatisfiedBy(offer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Base/SharedKernel/Specification/OrSpecification.cs b/DDD.Base/SharedKernel/Specification/OrSpecification.cs
new file mode 100644
index 0000000..3537ea0
--- /dev/null
+++ b/DDD.Base/SharedKernel/Specification/OrSpecification.cs
@@ -0,0 +1,19 @@
+namespace DDD.Base.SharedKernel.Specification
+{
+ public class OrSpecification : CompositeSpecification
+ {
+ private ISpecification _a;
+ private ISpecification _b;
+
+ public OrSpecification(ISpecification a, ISpecification b)
+ {
+ _a = a;
+ _b = b;
+ }
+
+ public override bool IsSatisfiedBy(T offer)
+ {
+ return _a.IsSatisfiedBy(offer) || _b.IsSatisfiedBy(offer);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/DDD.Infrastructure.csproj b/DDD.Infrastructure/DDD.Infrastructure.csproj
new file mode 100644
index 0000000..8cf0253
--- /dev/null
+++ b/DDD.Infrastructure/DDD.Infrastructure.csproj
@@ -0,0 +1,97 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}
+ Library
+ Properties
+ DDD.Infrastructure
+ DDD.Infrastructure
+ v4.5.2
+ 512
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Automatonymous.3.3.0\lib\net452\Automatonymous.dll
+ True
+
+
+ ..\packages\Castle.Core.3.3.0\lib\net45\Castle.Core.dll
+ True
+
+
+ ..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll
+ True
+
+
+ ..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll
+ True
+
+
+ ..\packages\NHibernate.4.0.4.4000\lib\net40\NHibernate.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {7d8d2feb-c2e5-4d54-8369-21de2d44984a}
+ CQRS.Base
+
+
+ {f8d43559-8792-498b-ab51-211ca04cb4df}
+ DDD.Base
+
+
+
+
+
\ No newline at end of file
diff --git a/DDD.Infrastructure/DependencyInjector.cs b/DDD.Infrastructure/DependencyInjector.cs
new file mode 100644
index 0000000..6484045
--- /dev/null
+++ b/DDD.Infrastructure/DependencyInjector.cs
@@ -0,0 +1,29 @@
+using Castle.Windsor;
+using DDD.Base.Domain;
+using System.Reflection;
+
+namespace DDD.Infrastructure
+{
+ public class DependencyInjector : IDependencyInjector
+ {
+ private readonly IWindsorContainer _container;
+
+ public DependencyInjector(IWindsorContainer container)
+ {
+ _container = container;
+ }
+
+ public void InjectDependencies(AggregateRoot aggregateRoot)
+ {
+ var fields = aggregateRoot.GetType().GetFields();
+ foreach (FieldInfo fieldInfo in fields)
+ {
+ if (fieldInfo.FieldType.IsInterface)
+ {
+ object iface = _container.Resolve(fieldInfo.FieldType);
+ fieldInfo.SetValue(aggregateRoot, iface);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/GenericRepository.cs b/DDD.Infrastructure/GenericRepository.cs
new file mode 100644
index 0000000..091fb86
--- /dev/null
+++ b/DDD.Infrastructure/GenericRepository.cs
@@ -0,0 +1,46 @@
+using DDD.Base.Domain;
+using NHibernate;
+
+namespace DDD.Infrastructure
+{
+ public abstract class GenericRepository : IGenericRepository
+ where TAggregateRoot : AggregateRoot
+ {
+ private readonly IDependencyInjector _dependencyInjector;
+ private readonly ISession _session;
+
+ public GenericRepository(ISession session, IDependencyInjector dependencyInjector)
+ {
+ _session = session;
+ _dependencyInjector = dependencyInjector;
+ }
+
+ public TAggregateRoot Load(AggregateId id)
+ {
+ var result = _session.Get(id);
+ if (result == null)
+ {
+ return null;
+ }
+ if (result.IsRemoved())
+ {
+ return null;
+ }
+ _dependencyInjector.InjectDependencies(result);
+
+ return result;
+ }
+
+ public void Save(TAggregateRoot aggregateRoot)
+ {
+ _session.SaveOrUpdate(aggregateRoot);
+ }
+
+ public void Delete(AggregateId id)
+ {
+ var obj = _session.Get(id);
+ obj.MarkAsRemoved();
+ _session.SaveOrUpdate(obj);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/ISystemEvent.cs b/DDD.Infrastructure/ISystemEvent.cs
new file mode 100644
index 0000000..0581ccb
--- /dev/null
+++ b/DDD.Infrastructure/ISystemEvent.cs
@@ -0,0 +1,6 @@
+namespace Photostock.Sales.Infrastructure
+{
+ public interface ISystemEvent
+ {
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/ISystemEventPublisher.cs b/DDD.Infrastructure/ISystemEventPublisher.cs
new file mode 100644
index 0000000..405e930
--- /dev/null
+++ b/DDD.Infrastructure/ISystemEventPublisher.cs
@@ -0,0 +1,7 @@
+namespace Photostock.Sales.Infrastructure
+{
+ public interface ISystemEventPublisher
+ {
+ void Publish(T @event) where T : ISystemEvent;
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/Properties/AssemblyInfo.cs b/DDD.Infrastructure/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..22d7b5a
--- /dev/null
+++ b/DDD.Infrastructure/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DDD.Infrastructure")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DDD.Infrastructure")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1f25c4fb-d5ea-46bb-ab2b-ac5582e1aa9e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/DDD.Infrastructure/Sagas/ISagaData.cs b/DDD.Infrastructure/Sagas/ISagaData.cs
new file mode 100644
index 0000000..d08fbc9
--- /dev/null
+++ b/DDD.Infrastructure/Sagas/ISagaData.cs
@@ -0,0 +1,9 @@
+using Automatonymous;
+
+namespace DDD.Infrastructure.Sagas
+{
+ public interface ISagaData
+ {
+ State CurrentState { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/Sagas/ISagaRepository.cs b/DDD.Infrastructure/Sagas/ISagaRepository.cs
new file mode 100644
index 0000000..0932129
--- /dev/null
+++ b/DDD.Infrastructure/Sagas/ISagaRepository.cs
@@ -0,0 +1,9 @@
+namespace DDD.Infrastructure.Sagas
+{
+ public interface ISagaRepository
+ {
+ void Save(string id, TSagaData sagaData);
+
+ TSagaData Load(string id);
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/Sagas/ISerializer.cs b/DDD.Infrastructure/Sagas/ISerializer.cs
new file mode 100644
index 0000000..5c89c03
--- /dev/null
+++ b/DDD.Infrastructure/Sagas/ISerializer.cs
@@ -0,0 +1,9 @@
+namespace DDD.Infrastructure.Sagas
+{
+ public interface ISerializer
+ {
+ T Deserialize(string serializedData) where T : class;
+
+ string Serialize(object sagaData);
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/Sagas/InMemorySagaRepository.cs b/DDD.Infrastructure/Sagas/InMemorySagaRepository.cs
new file mode 100644
index 0000000..b21a874
--- /dev/null
+++ b/DDD.Infrastructure/Sagas/InMemorySagaRepository.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace DDD.Infrastructure.Sagas
+{
+ public class InMemorySagaRepository : ISagaRepository where TSagaData : class
+ {
+ public Dictionary Values = new Dictionary();
+
+ public void Save(string id, TSagaData sagaData)
+ {
+ Values[id] = sagaData;
+ }
+
+ public TSagaData Load(string id)
+ {
+ if (Values.ContainsKey(id))
+ {
+ return Values[id];
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/Sagas/SagaManager.cs b/DDD.Infrastructure/Sagas/SagaManager.cs
new file mode 100644
index 0000000..7b8f34d
--- /dev/null
+++ b/DDD.Infrastructure/Sagas/SagaManager.cs
@@ -0,0 +1,45 @@
+using Automatonymous;
+using DDD.Base.Sagas;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace DDD.Infrastructure.Sagas
+{
+ public class SagaManager : ISagaManager where TSagaMachine : AutomatonymousStateMachine where TSagaData : class, ISagaData, new()
+ {
+ private ISagaRepository _sagaRepository;
+ private Dictionary> _correlationIdFuncs = new Dictionary>();
+ public TSagaMachine SagaMachine { get; private set; }
+
+ public SagaManager(TSagaMachine sagaMachine, ISagaRepository sagaRepository)
+ {
+ _sagaRepository = sagaRepository;
+ SagaMachine = sagaMachine;
+ }
+
+ protected void CorrelateEvent(Func correlationIdFunc)
+ {
+ _correlationIdFuncs.Add(typeof(TEvent), e => correlationIdFunc((TEvent)e));
+ }
+
+ public void ProcessMessage(TMessage message)
+ {
+ Event @event = SagaMachine.Events.OfType>().FirstOrDefault();
+
+ TMessage eventData = message;
+
+ string correlationId = _correlationIdFuncs[typeof(TMessage)](eventData);
+
+ TSagaData sagaData = _sagaRepository.Load(correlationId);
+ if (sagaData == null)
+ {
+ sagaData = new TSagaData();
+ }
+
+ SagaMachine.RaiseEvent(sagaData, @event, eventData);
+
+ _sagaRepository.Save(correlationId, sagaData);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/Sagas/SagaXmlSerilizer.cs b/DDD.Infrastructure/Sagas/SagaXmlSerilizer.cs
new file mode 100644
index 0000000..ce2cc14
--- /dev/null
+++ b/DDD.Infrastructure/Sagas/SagaXmlSerilizer.cs
@@ -0,0 +1,25 @@
+using System.IO;
+using System.Xml.Serialization;
+
+namespace DDD.Infrastructure.Sagas
+{
+ public class SagaXmlSerilizer : ISerializer
+ {
+ public T Deserialize(string serializedData) where T : class
+ {
+ using (StringReader sr = new StringReader(serializedData))
+ {
+ return new XmlSerializer(typeof(T)).Deserialize(sr) as T;
+ }
+ }
+
+ public string Serialize(object sagaData)
+ {
+ using (StringWriter sw = new StringWriter())
+ {
+ new XmlSerializer(sagaData.GetType()).Serialize(sw, sagaData);
+ return sw.GetStringBuilder().ToString();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DDD.Infrastructure/packages.config b/DDD.Infrastructure/packages.config
new file mode 100644
index 0000000..2507958
--- /dev/null
+++ b/DDD.Infrastructure/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess.Tests/OrderSagaManagerTests.cs b/PhotoStock.BusinessProcess.Tests/OrderSagaManagerTests.cs
new file mode 100644
index 0000000..9c48cda
--- /dev/null
+++ b/PhotoStock.BusinessProcess.Tests/OrderSagaManagerTests.cs
@@ -0,0 +1,69 @@
+using CQRS.Base.Command;
+using DDD.Base.Domain;
+using DDD.Infrastructure.Sagas;
+using Moq;
+using NUnit.Framework;
+using PhotoStock.Invoicing.Contract.Events;
+using PhotoStock.Sales.Contract.Events;
+using PhotoStock.Shipping.Contract.Commands;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PhotoStock.BusinessProcess.Tests
+{
+ [TestFixture]
+ public class OrderSagaManagerTests
+ {
+ private InMemorySagaRepository _repository;
+ private Mock _commandSender;
+ private OrderSagaManager _manager;
+
+ [SetUp]
+ public void Setup()
+ {
+ _repository = new InMemorySagaRepository();
+ _commandSender = new Mock();
+ _manager = new OrderSagaManager(_repository, _commandSender.Object);
+ }
+
+ [Test]
+ public void RaiseEvent_Should_write_to_db_saga_contents()
+ {
+ // Arrange
+ const string orderId = "1";
+ var orderConfirmedEvent = new OrderCreatedEvent(orderId);
+
+ // Act
+ _manager.ProcessMessage(orderConfirmedEvent);
+
+ // Assert
+ Assert.IsTrue(_repository.Values.ContainsKey(orderConfirmedEvent.OrderId));
+ Assert.IsTrue(orderId == _repository.Values[orderId].OrderId);
+ }
+
+ [Test]
+ public void OrderInvoicedEvent_Should_write_fill_invoiceNumber_and_send_shipCommand()
+ {
+ // Arrange
+ const string invoiceNumber = "FV/233";
+ const string orderId = "12";
+ var orderInvoicedEvent = new OrderInvoicedEvent(orderId, invoiceNumber);
+
+ _repository.Values[orderId] = new OrderSagaData()
+ {
+ OrderId = orderId,
+ CurrentState = _manager.SagaMachine.OrderConfirmed
+ };
+
+ // Act
+ _manager.ProcessMessage(orderInvoicedEvent);
+
+ // Assert
+ _commandSender.Verify(f => f.Send(It.Is(d => d.OrderId == orderId)));
+ Assert.IsTrue(invoiceNumber == _repository.Values[orderId].InvoiceNumber);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess.Tests/PhotoStock.BusinessProcess.Tests.csproj b/PhotoStock.BusinessProcess.Tests/PhotoStock.BusinessProcess.Tests.csproj
new file mode 100644
index 0000000..e57e5ee
--- /dev/null
+++ b/PhotoStock.BusinessProcess.Tests/PhotoStock.BusinessProcess.Tests.csproj
@@ -0,0 +1,102 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {5C0936A5-3185-44C5-9B6B-FEB039CFB6F7}
+ Library
+ Properties
+ PhotoStock.BusinessProcess.Tests
+ PhotoStock.BusinessProcess.Tests
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Automatonymous.3.3.0\lib\net452\Automatonymous.dll
+ True
+
+
+ ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll
+ True
+
+
+ ..\packages\NUnit.2.6.4\lib\nunit.framework.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}
+ CQRS.Base
+
+
+ {f8d43559-8792-498b-ab51-211ca04cb4df}
+ DDD.Base
+
+
+ {1f25c4fb-d5ea-46bb-ab2b-ac5582e1aa9e}
+ DDD.Infrastructure
+
+
+ {6B0EA748-FC9A-467B-B3D4-A2A025EEBB29}
+ PhotoStock.BusinessProcess
+
+
+ {265016F3-AE52-4167-926A-52924366E7DD}
+ PhotoStock.Invoicing.Contract
+
+
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ PhotoStock.Sales.Contract
+
+
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}
+ PhotoStock.Shipping.Contract
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess.Tests/Properties/AssemblyInfo.cs b/PhotoStock.BusinessProcess.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..230e757
--- /dev/null
+++ b/PhotoStock.BusinessProcess.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.BusinessProcess.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.BusinessProcess.Tests")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5c0936a5-3185-44c5-9b6b-feb039cfb6f7")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.BusinessProcess.Tests/packages.config b/PhotoStock.BusinessProcess.Tests/packages.config
new file mode 100644
index 0000000..f25d7d2
--- /dev/null
+++ b/PhotoStock.BusinessProcess.Tests/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess/OrderSaga.cs b/PhotoStock.BusinessProcess/OrderSaga.cs
new file mode 100644
index 0000000..a1ca3ae
--- /dev/null
+++ b/PhotoStock.BusinessProcess/OrderSaga.cs
@@ -0,0 +1,37 @@
+using Automatonymous;
+using CQRS.Base.Command;
+using PhotoStock.Invoicing.Contract.Commands;
+using PhotoStock.Invoicing.Contract.Events;
+using PhotoStock.Sales.Contract.Events;
+using PhotoStock.Shipping.Contract.Commands;
+using PhotoStock.Shipping.Contract.Events;
+using System.Linq;
+using OrderItem = PhotoStock.Invoicing.Contract.Commands.OrderItem;
+
+namespace PhotoStock.BusinessProcess
+{
+ public class OrderSaga : AutomatonymousStateMachine
+ {
+ private ICommandSender _commandSender;
+
+ public OrderSaga(ICommandSender commandSender)
+ {
+ _commandSender = commandSender;
+
+ Event(() => OrderCreatedEvent);
+ Event(() => OrderConfirmedEvent);
+ Event(() => OrderShippedEvent);
+ Event(() => OrderInvoicedEvent);
+ }
+
+ public State OrderCreated { get; set; }
+ public State OrderShipped { get; set; }
+ public State OrderConfirmed { get; set; }
+ public State OrderInvoiced { get; set; }
+
+ public Event OrderCreatedEvent { get; set; }
+ public Event OrderShippedEvent { get; set; }
+ public Event OrderConfirmedEvent { get; set; }
+ public Event OrderInvoicedEvent { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess/OrderSagaData.cs b/PhotoStock.BusinessProcess/OrderSagaData.cs
new file mode 100644
index 0000000..1f8f387
--- /dev/null
+++ b/PhotoStock.BusinessProcess/OrderSagaData.cs
@@ -0,0 +1,14 @@
+using Automatonymous;
+using DDD.Base.Domain;
+using DDD.Infrastructure.Sagas;
+
+namespace PhotoStock.BusinessProcess
+{
+ public class OrderSagaData : ISagaData
+ {
+ public State CurrentState { get; set; }
+ public AggregateId OrderId { get; set; }
+ public AggregateId InvoiceNumber { get; set; }
+ public AggregateId ShipementId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess/PhotoStock.BusinessProcess.csproj b/PhotoStock.BusinessProcess/PhotoStock.BusinessProcess.csproj
new file mode 100644
index 0000000..78e743b
--- /dev/null
+++ b/PhotoStock.BusinessProcess/PhotoStock.BusinessProcess.csproj
@@ -0,0 +1,109 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {6B0EA748-FC9A-467B-B3D4-A2A025EEBB29}
+ Library
+ Properties
+ PhotoStock.BusinessProcess
+ PhotoStock.BusinessProcess
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Automatonymous.3.3.0\lib\net452\Automatonymous.dll
+ True
+
+
+ ..\packages\Automatonymous.NHibernate.3.3.0\lib\net452\Automatonymous.NHibernateIntegration.dll
+ True
+
+
+ ..\packages\Iesi.Collections.4.0.1.4000\lib\net40\Iesi.Collections.dll
+ True
+
+
+ ..\packages\NHibernate.4.0.4.4000\lib\net40\NHibernate.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}
+ CQRS.Base
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}
+ DDD.Infrastructure
+
+
+ {265016F3-AE52-4167-926A-52924366E7DD}
+ PhotoStock.Invoicing.Contract
+
+
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ PhotoStock.Sales.Contract
+
+
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}
+ PhotoStock.SharedKernel
+
+
+ {DB22ADE0-E49E-4B7E-9329-5AEA5F82072C}
+ PhotoStock.Shipping.Application
+
+
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}
+ PhotoStock.Shipping.Contract
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess/Properties/AssemblyInfo.cs b/PhotoStock.BusinessProcess/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..df2bb0e
--- /dev/null
+++ b/PhotoStock.BusinessProcess/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.BusinnessProcess")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.BusinnessProcess")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6b0ea748-fc9a-467b-b3d4-a2a025eebb29")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.BusinessProcess/SagaManager.cs b/PhotoStock.BusinessProcess/SagaManager.cs
new file mode 100644
index 0000000..fe71f1c
--- /dev/null
+++ b/PhotoStock.BusinessProcess/SagaManager.cs
@@ -0,0 +1,20 @@
+using CQRS.Base.Command;
+using DDD.Infrastructure.Sagas;
+using PhotoStock.Invoicing.Contract.Events;
+using PhotoStock.Sales.Contract.Events;
+using PhotoStock.Shipping.Contract.Events;
+
+namespace PhotoStock.BusinessProcess
+{
+ public class OrderSagaManager : SagaManager
+ {
+ public OrderSagaManager(ISagaRepository sagaRepository, ICommandSender commandSender)
+ : base(new OrderSaga(commandSender), sagaRepository)
+ {
+ CorrelateEvent(f => f.OrderId);
+ CorrelateEvent(f => f.OrderId);
+ CorrelateEvent(f => f.OrderId);
+ CorrelateEvent(f => f.OrderId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.BusinessProcess/packages.config b/PhotoStock.BusinessProcess/packages.config
new file mode 100644
index 0000000..4c12e27
--- /dev/null
+++ b/PhotoStock.BusinessProcess/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Application/PhotoStock.Invoicing.Application.csproj b/PhotoStock.Invoicing.Application/PhotoStock.Invoicing.Application.csproj
new file mode 100644
index 0000000..dde7706
--- /dev/null
+++ b/PhotoStock.Invoicing.Application/PhotoStock.Invoicing.Application.csproj
@@ -0,0 +1,87 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {91D4A03B-CCE7-4A9A-AA80-626251967A2B}
+ Library
+ Properties
+ PhotoStock.Invoicing.Application
+ PhotoStock.Invoicing.Application
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}
+ CQRS.Base
+
+
+ {f8d43559-8792-498b-ab51-211ca04cb4df}
+ DDD.Base
+
+
+ {1f25c4fb-d5ea-46bb-ab2b-ac5582e1aa9e}
+ DDD.Infrastructure
+
+
+ {265016F3-AE52-4167-926A-52924366E7DD}
+ PhotoStock.Invoicing.Contract
+
+
+ {F686EDF5-2B9C-4DE1-B197-785B38BE4B97}
+ PhotoStock.Invoicing.Domain
+
+
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ PhotoStock.Sales.Contract
+
+
+ {266ff480-2b3a-40c5-b01c-721c9a4d79d3}
+ PhotoStock.SharedKernel
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Application/Properties/AssemblyInfo.cs b/PhotoStock.Invoicing.Application/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e825632
--- /dev/null
+++ b/PhotoStock.Invoicing.Application/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Invoicing.Application")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Invoicing.Application")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("91d4a03b-cce7-4a9a-aa80-626251967a2b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Invoicing.Contract/Commands/InvoiceOrderCommand.cs b/PhotoStock.Invoicing.Contract/Commands/InvoiceOrderCommand.cs
new file mode 100644
index 0000000..98c8051
--- /dev/null
+++ b/PhotoStock.Invoicing.Contract/Commands/InvoiceOrderCommand.cs
@@ -0,0 +1,24 @@
+using DDD.Base.Domain;
+using PhotoStock.SharedKernel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PhotoStock.Invoicing.Contract.Commands
+{
+ public class InvoiceOrderCommand
+ {
+ public AggregateId OrderId { get; set; }
+ public ClientData ClientData { get; set; }
+ public IEnumerable Items { get; set; }
+
+ public InvoiceOrderCommand(AggregateId orderId, ClientData clientData, IEnumerable items)
+ {
+ OrderId = orderId;
+ ClientData = clientData;
+ Items = items;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Contract/Commands/OrderItem.cs b/PhotoStock.Invoicing.Contract/Commands/OrderItem.cs
new file mode 100644
index 0000000..36747b4
--- /dev/null
+++ b/PhotoStock.Invoicing.Contract/Commands/OrderItem.cs
@@ -0,0 +1,18 @@
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Invoicing.Contract.Commands
+{
+ public class OrderItem
+ {
+ public OrderItem(ProductData productData, int quantity, Money totalCost)
+ {
+ ProductData = productData;
+ Quantity = quantity;
+ TotalCost = totalCost;
+ }
+
+ public Money TotalCost { get; set; }
+ public ProductData ProductData { get; set; }
+ public int Quantity { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Contract/Events/OrderInvoicedEvent.cs b/PhotoStock.Invoicing.Contract/Events/OrderInvoicedEvent.cs
new file mode 100644
index 0000000..0bda951
--- /dev/null
+++ b/PhotoStock.Invoicing.Contract/Events/OrderInvoicedEvent.cs
@@ -0,0 +1,16 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Invoicing.Contract.Events
+{
+ public class OrderInvoicedEvent : IDomainEvent
+ {
+ public AggregateId OrderId { get; private set; }
+ public AggregateId InvoiceNumber { get; private set; }
+
+ public OrderInvoicedEvent(AggregateId orderId, AggregateId invoiceNumber)
+ {
+ OrderId = orderId;
+ InvoiceNumber = invoiceNumber;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Contract/PhotoStock.Invoicing.Contract.csproj b/PhotoStock.Invoicing.Contract/PhotoStock.Invoicing.Contract.csproj
new file mode 100644
index 0000000..ff9bde0
--- /dev/null
+++ b/PhotoStock.Invoicing.Contract/PhotoStock.Invoicing.Contract.csproj
@@ -0,0 +1,70 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {265016F3-AE52-4167-926A-52924366E7DD}
+ Library
+ Properties
+ PhotoStock.Invoicing.Contract
+ PhotoStock.Invoicing.Contract
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ PhotoStock.Sales.Contract
+
+
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}
+ PhotoStock.SharedKernel
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Contract/Properties/AssemblyInfo.cs b/PhotoStock.Invoicing.Contract/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..43c2910
--- /dev/null
+++ b/PhotoStock.Invoicing.Contract/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Invoicing.Contract")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Invoicing.Contract")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("265016f3-ae52-4167-926a-52924366e7dd")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Invoicing.Domain/IInvoiceFactory.cs b/PhotoStock.Invoicing.Domain/IInvoiceFactory.cs
new file mode 100644
index 0000000..fae5506
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/IInvoiceFactory.cs
@@ -0,0 +1,10 @@
+using DDD.Base.Domain;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public interface IInvoiceFactory
+ {
+ Invoice Create(AggregateId orderId, ClientData clientData);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/IInvoiceNumberGenerator.cs b/PhotoStock.Invoicing.Domain/IInvoiceNumberGenerator.cs
new file mode 100644
index 0000000..606f922
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/IInvoiceNumberGenerator.cs
@@ -0,0 +1,9 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public interface IInvoiceNumberGenerator
+ {
+ AggregateId GenerateNextInvoiceNumber();
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/ITaxPolicy.cs b/PhotoStock.Invoicing.Domain/ITaxPolicy.cs
new file mode 100644
index 0000000..290514b
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/ITaxPolicy.cs
@@ -0,0 +1,10 @@
+using PhotoStock.Invoicing.Domain.TaxPolicy;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public interface ITaxPolicy
+ {
+ Tax CalculateTax(ProductType productType, Money net);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/Invoice.cs b/PhotoStock.Invoicing.Domain/Invoice.cs
new file mode 100644
index 0000000..68fc927
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/Invoice.cs
@@ -0,0 +1,33 @@
+using DDD.Base.Domain;
+using PhotoStock.SharedKernel;
+using System.Collections.Generic;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public class Invoice : AggregateRoot
+ {
+ public ClientData Client { get; private set; }
+ public Money Net { get; private set; }
+ public Money Gros { get; private set; }
+ public List _items = new List();
+
+ public Invoice(AggregateId invoiceId, ClientData client) : base(invoiceId)
+ {
+ Client = client;
+ Net = Money.ZERO;
+ Gros = Money.ZERO;
+ }
+
+ private Invoice()
+ {
+ }
+
+ public void AddItem(InvoiceLine item)
+ {
+ _items.Add(item);
+
+ Net = Net.Add(item.Net);
+ Gros = Gros.Add(item.Gros);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/InvoiceFactory.cs b/PhotoStock.Invoicing.Domain/InvoiceFactory.cs
new file mode 100644
index 0000000..e73e677
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/InvoiceFactory.cs
@@ -0,0 +1,32 @@
+using DDD.Base.Domain;
+using PhotoStock.Invoicing.Contract.Events;
+using PhotoStock.SharedKernel;
+using System;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public class InvoiceFactory : IInvoiceFactory
+ {
+ private IInvoiceNumberGenerator _numberGenerator;
+ private IDomainEventPublisher _eventPublisher;
+ private IDependencyInjector _dependencyInjector;
+
+ public InvoiceFactory(IDomainEventPublisher eventPublisher, IInvoiceNumberGenerator numberGenerator, IDependencyInjector dependencyInjector)
+ {
+ _eventPublisher = eventPublisher;
+ _numberGenerator = numberGenerator;
+ _dependencyInjector = dependencyInjector;
+ }
+
+ public Invoice Create(AggregateId orderId, ClientData clientData)
+ {
+ AggregateId number = _numberGenerator.GenerateNextInvoiceNumber();
+ _eventPublisher.Publish(new OrderInvoicedEvent(orderId, number));
+
+ Invoice invoice = new Invoice(number, clientData);
+ _dependencyInjector.InjectDependencies(invoice);
+
+ return invoice;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/InvoiceLine.cs b/PhotoStock.Invoicing.Domain/InvoiceLine.cs
new file mode 100644
index 0000000..15282fd
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/InvoiceLine.cs
@@ -0,0 +1,27 @@
+using DDD.Base.Domain;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public class InvoiceLine : Entity
+ {
+ public ProductData Product { get; private set; }
+ public int Quantity { get; private set; }
+ public Money Net { get; private set; }
+ public Money Gros { get; private set; }
+ public Tax Tax { get; private set; }
+
+ public InvoiceLine()
+ {
+ }
+
+ public InvoiceLine(ProductData product, int quantity, Money net, Tax tax)
+ {
+ Product = product;
+ Quantity = quantity;
+ Net = net;
+ Tax = tax;
+ Gros = Net.Add(tax.Amount);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/InvoiceRepository.cs b/PhotoStock.Invoicing.Domain/InvoiceRepository.cs
new file mode 100644
index 0000000..47aa00d
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/InvoiceRepository.cs
@@ -0,0 +1,8 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public interface IInvoiceRepository : IGenericRepository
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/PhotoStock.Invoicing.Domain.csproj b/PhotoStock.Invoicing.Domain/PhotoStock.Invoicing.Domain.csproj
new file mode 100644
index 0000000..74c7f6b
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/PhotoStock.Invoicing.Domain.csproj
@@ -0,0 +1,76 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {F686EDF5-2B9C-4DE1-B197-785B38BE4B97}
+ Library
+ Properties
+ PhotoStock.Invoicing.Domain
+ PhotoStock.Invoicing.Domain
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {f8d43559-8792-498b-ab51-211ca04cb4df}
+ DDD.Base
+
+
+ {265016F3-AE52-4167-926A-52924366E7DD}
+ PhotoStock.Invoicing.Contract
+
+
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}
+ PhotoStock.SharedKernel
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/Properties/AssemblyInfo.cs b/PhotoStock.Invoicing.Domain/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..84a945a
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Invoicing.Domain")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Invoicing.Domain")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f686edf5-2b9c-4de1-b197-785b38be4b97")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Invoicing.Domain/Tax.cs b/PhotoStock.Invoicing.Domain/Tax.cs
new file mode 100644
index 0000000..5f87d45
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/Tax.cs
@@ -0,0 +1,22 @@
+using DDD.Base.Domain;
+using PhotoStock.SharedKernel;
+using System;
+
+namespace PhotoStock.Invoicing.Domain
+{
+ public class Tax : ValueObject
+ {
+ public Money Amount { get; private set; }
+ public string Description { get; private set; }
+
+ public Tax()
+ {
+ }
+
+ public Tax(Money amount, String description)
+ {
+ Amount = amount;
+ Description = description;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Invoicing.Domain/TaxPolicy/DefaultTaxPolicy.cs b/PhotoStock.Invoicing.Domain/TaxPolicy/DefaultTaxPolicy.cs
new file mode 100644
index 0000000..86d1dd0
--- /dev/null
+++ b/PhotoStock.Invoicing.Domain/TaxPolicy/DefaultTaxPolicy.cs
@@ -0,0 +1,34 @@
+using PhotoStock.SharedKernel;
+using System;
+
+namespace PhotoStock.Invoicing.Domain.TaxPolicy
+{
+ public class DefaultTaxPolicy : ITaxPolicy
+ {
+ public Tax CalculateTax(ProductType productType, Money net)
+ {
+ decimal ratio;
+ string desc = null;
+
+ switch (productType)
+ {
+ case ProductType.Printed:
+ ratio = (decimal)0.05;
+ desc = "5% (D)";
+ break;
+
+ case ProductType.Electronic:
+ ratio = (decimal)0.23;
+ desc = "23%";
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException(productType + " not Handled");
+ }
+
+ Money tax = net * ratio;
+
+ return new Tax(tax, desc);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Application/PhotoStock.Sales.Application.csproj b/PhotoStock.Sales.Application/PhotoStock.Sales.Application.csproj
new file mode 100644
index 0000000..390a690
--- /dev/null
+++ b/PhotoStock.Sales.Application/PhotoStock.Sales.Application.csproj
@@ -0,0 +1,105 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {502D416A-D97E-46F6-B47F-85AB0BFDCD3A}
+ Library
+ Properties
+ PhotoStock.Sales.Application
+ PhotoStock.Sales.Application
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+ ..\packages\Castle.Core.3.3.0\lib\net45\Castle.Core.dll
+ True
+
+
+ ..\packages\Castle.Windsor.3.3.0\lib\net45\Castle.Windsor.dll
+ True
+
+
+ ..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}
+ CQRS.Base
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ PhotoStock.Sales.Contract
+
+
+ {2230C68D-558A-463F-B3ED-427968DECB2E}
+ PhotoStock.Sales.Domain
+
+
+ {266ff480-2b3a-40c5-b01c-721c9a4d79d3}
+ PhotoStock.SharedKernel
+
+
+ {2FC58C62-FE65-46C7-989E-180C2B8E41EE}
+ PhotoStock.System
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Sales.Application/Properties/AssemblyInfo.cs b/PhotoStock.Sales.Application/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..611ad16
--- /dev/null
+++ b/PhotoStock.Sales.Application/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Sales.Application")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Sales.Application")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("502d416a-d97e-46f6-b47f-85ab0bfdcd3a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Sales.Application/Services/OrderingService/IOrderingService.cs b/PhotoStock.Sales.Application/Services/OrderingService/IOrderingService.cs
new file mode 100644
index 0000000..034307a
--- /dev/null
+++ b/PhotoStock.Sales.Application/Services/OrderingService/IOrderingService.cs
@@ -0,0 +1,17 @@
+namespace PhotoStock.Sales.Contract
+{
+ public interface IOrderingService
+ {
+ // 1.
+ //AggregateId CreateOrder();
+
+ // 2.
+ //void AddPicture(AggregateId orderId, AggregateId productId);
+
+ // 3.
+ //Offer CalculateOffer(AggregateId orderId);
+
+ // 4.
+ //void Confirm(AggregateId orderId, Offer seenOffer);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Application/Services/OrderingService/OrderingService.cs b/PhotoStock.Sales.Application/Services/OrderingService/OrderingService.cs
new file mode 100644
index 0000000..8ac0cbe
--- /dev/null
+++ b/PhotoStock.Sales.Application/Services/OrderingService/OrderingService.cs
@@ -0,0 +1,38 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel.Specification;
+using PhotoStock.Sales.Contract;
+using PhotoStock.Sales.Domain.Client;
+using PhotoStock.Sales.Domain.Offer;
+using PhotoStock.Sales.Domain.Offer.Discount;
+using PhotoStock.Sales.Domain.ProductsCatalog;
+using PhotoStock.Sales.Domain.Purchase;
+using PhotoStock.Sales.Domain.Reservation;
+using PhotoStock.System;
+using System;
+
+namespace PhotoStock.Sales.Application.Services.OrderingService
+{
+ public class OrderingService : IOrderingService
+ {
+ private ISystemContext _systemContext;
+ private IClientRepository _clientRepository;
+
+ public OrderingService(
+ ISystemContext systemContext,
+ IClientRepository clientRepository)
+ {
+ _systemContext = systemContext;
+ _clientRepository = clientRepository;
+ }
+
+ public AggregateId CreateOrder()
+ {
+ throw new NotImplementedException();
+ }
+
+ private Client LoadClient()
+ {
+ return _clientRepository.Load(_systemContext.SystemUser.ClientId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Application/Services/PurchaseService/IPaymentService.cs b/PhotoStock.Sales.Application/Services/PurchaseService/IPaymentService.cs
new file mode 100644
index 0000000..2e8c439
--- /dev/null
+++ b/PhotoStock.Sales.Application/Services/PurchaseService/IPaymentService.cs
@@ -0,0 +1,9 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Application.Services.PurchaseService
+{
+ internal interface IPaymentService
+ {
+ void ConfirmOrderPayment(AggregateId orderId);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Application/Services/PurchaseService/PaymentService.cs b/PhotoStock.Sales.Application/Services/PurchaseService/PaymentService.cs
new file mode 100644
index 0000000..e6470cd
--- /dev/null
+++ b/PhotoStock.Sales.Application/Services/PurchaseService/PaymentService.cs
@@ -0,0 +1,23 @@
+using DDD.Base.Domain;
+using PhotoStock.Sales.Domain.Client;
+using PhotoStock.Sales.Domain.Purchase;
+
+namespace PhotoStock.Sales.Application.Services.PurchaseService
+{
+ internal class PaymentService : IPaymentService
+ {
+ private readonly IPurchaseRepository _purchaseRepository;
+
+ public PaymentService(IPurchaseRepository purchaseRepository)
+ {
+ _purchaseRepository = purchaseRepository;
+ }
+
+ public void ConfirmOrderPayment(AggregateId orderId)
+ {
+ Purchase purchase = _purchaseRepository.Load(orderId);
+ purchase.Confirm();
+ _purchaseRepository.Save(purchase);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Application/packages.config b/PhotoStock.Sales.Application/packages.config
new file mode 100644
index 0000000..1a32a6a
--- /dev/null
+++ b/PhotoStock.Sales.Application/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Sales.Contract/Events/OrderConfirmedEvent.cs b/PhotoStock.Sales.Contract/Events/OrderConfirmedEvent.cs
new file mode 100644
index 0000000..8eb5900
--- /dev/null
+++ b/PhotoStock.Sales.Contract/Events/OrderConfirmedEvent.cs
@@ -0,0 +1,21 @@
+using DDD.Base.Domain;
+using Photostock.Sales.Infrastructure;
+using PhotoStock.SharedKernel;
+using System.Collections.Generic;
+
+namespace PhotoStock.Sales.Contract.Events
+{
+ public class OrderConfirmedEvent : ISystemEvent
+ {
+ public AggregateId OrderId { get; private set; }
+ public ClientData ClientData { get; private set; }
+ public IEnumerable Items { get; private set; }
+
+ public OrderConfirmedEvent(AggregateId orderId, ClientData clientData, IEnumerable items)
+ {
+ OrderId = orderId;
+ ClientData = clientData;
+ Items = items;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Contract/Events/OrderCreatedEvent.cs b/PhotoStock.Sales.Contract/Events/OrderCreatedEvent.cs
new file mode 100644
index 0000000..3b640f1
--- /dev/null
+++ b/PhotoStock.Sales.Contract/Events/OrderCreatedEvent.cs
@@ -0,0 +1,15 @@
+using DDD.Base.Domain;
+using Photostock.Sales.Infrastructure;
+
+namespace PhotoStock.Sales.Contract.Events
+{
+ public class OrderCreatedEvent : ISystemEvent
+ {
+ public AggregateId OrderId { get; private set; }
+
+ public OrderCreatedEvent(AggregateId orderId)
+ {
+ OrderId = orderId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Contract/Events/OrderItem.cs b/PhotoStock.Sales.Contract/Events/OrderItem.cs
new file mode 100644
index 0000000..ab36c05
--- /dev/null
+++ b/PhotoStock.Sales.Contract/Events/OrderItem.cs
@@ -0,0 +1,10 @@
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Sales.Contract.Events
+{
+ public class OrderItem
+ {
+ public ProductData ProductData { get; set; }
+ public Money TotalCost { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Contract/PhotoStock.Sales.Contract.csproj b/PhotoStock.Sales.Contract/PhotoStock.Sales.Contract.csproj
new file mode 100644
index 0000000..f769a30
--- /dev/null
+++ b/PhotoStock.Sales.Contract/PhotoStock.Sales.Contract.csproj
@@ -0,0 +1,73 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ Library
+ Properties
+ PhotoStock.Sales.Contract
+ PhotoStock.Sales.Contract
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}
+ DDD.Infrastructure
+
+
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}
+ PhotoStock.SharedKernel
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Sales.Contract/Properties/AssemblyInfo.cs b/PhotoStock.Sales.Contract/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..93c9970
--- /dev/null
+++ b/PhotoStock.Sales.Contract/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Sales.Contract")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Sales.Contract")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ea7d831a-03d1-4a08-805c-3e450ea024bc")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Sales.Domain/Client/Client.cs b/PhotoStock.Sales.Domain/Client/Client.cs
new file mode 100644
index 0000000..3579af4
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Client/Client.cs
@@ -0,0 +1,40 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Sales.Domain.Client
+{
+ public class Client : AggregateRoot
+ {
+ private string _name;
+
+ public Client(string name)
+ {
+ _name = name;
+ }
+
+ public ClientData GenerateSnapshot()
+ {
+ return new ClientData(AggregateId, _name);
+ }
+
+ public bool CanAfford(Money amount)
+ {
+ return true;//TODO explore domain rules ex: credit limit
+ }
+
+ public void Charge(Money amount)
+ {
+ if (!CanAfford(amount))
+ {
+ DomainError("Can not afford: " + amount);
+ }
+ // TODO facade to the payment module
+ }
+
+ public bool CanMakeReservation()
+ {
+ return true; //TODO explore domain rules (ex: cleint's debts, stataus etc)
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Client/IClientRepository.cs b/PhotoStock.Sales.Domain/Client/IClientRepository.cs
new file mode 100644
index 0000000..c97827e
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Client/IClientRepository.cs
@@ -0,0 +1,8 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Domain.Client
+{
+ public interface IClientRepository : IGenericRepository
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Address.cs b/PhotoStock.Sales.Domain/Offer/Address.cs
new file mode 100644
index 0000000..66121f4
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Address.cs
@@ -0,0 +1,13 @@
+using PhotoStock.Sales.Domain.Offer.Specification;
+
+namespace PhotoStock.Sales.Domain.Offer
+{
+ public class Address
+ {
+ public Locale Country { get; set; }
+ }
+
+ public class Locale
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Discount/Discount.cs b/PhotoStock.Sales.Domain/Offer/Discount/Discount.cs
new file mode 100644
index 0000000..19f821e
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Discount/Discount.cs
@@ -0,0 +1,18 @@
+using DDD.Base.Domain;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Sales.Domain.Offer.Discount
+{
+
+ public class Discount : ValueObject
+ {
+ public string Cause { get; set; }
+ public Money Value { get; set; }
+
+ public Discount(string cause, Money value)
+ {
+ Cause = cause;
+ Value = value;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Discount/DiscountFactory.cs b/PhotoStock.Sales.Domain/Offer/Discount/DiscountFactory.cs
new file mode 100644
index 0000000..a4b8a9e
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Discount/DiscountFactory.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace PhotoStock.Sales.Domain.Offer.Discount
+{
+ public class DiscountFactory : IDiscountFactory
+ {
+ public IDiscountPolicy Create(Client.Client client)
+ {
+ IDiscountPolicy result = new DiscountPolicy();
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Discount/DiscountPolicy.cs b/PhotoStock.Sales.Domain/Offer/Discount/DiscountPolicy.cs
new file mode 100644
index 0000000..a4a0c1e
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Discount/DiscountPolicy.cs
@@ -0,0 +1,15 @@
+using PhotoStock.Sales.Domain.ProductsCatalog;
+using PhotoStock.SharedKernel;
+using System;
+
+namespace PhotoStock.Sales.Domain.Offer.Discount
+{
+ internal class DiscountPolicy : IDiscountPolicy
+ {
+ public Discount ApplyDiscount()
+ {
+ //TODO;
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Discount/IDiscountFactory.cs b/PhotoStock.Sales.Domain/Offer/Discount/IDiscountFactory.cs
new file mode 100644
index 0000000..91d29c5
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Discount/IDiscountFactory.cs
@@ -0,0 +1,7 @@
+namespace PhotoStock.Sales.Domain.Offer.Discount
+{
+ public interface IDiscountFactory
+ {
+ IDiscountPolicy Create(Client.Client client);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Discount/IDiscountPolicy.cs b/PhotoStock.Sales.Domain/Offer/Discount/IDiscountPolicy.cs
new file mode 100644
index 0000000..56ae28f
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Discount/IDiscountPolicy.cs
@@ -0,0 +1,10 @@
+using PhotoStock.Sales.Domain.ProductsCatalog;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Sales.Domain.Offer.Discount
+{
+ public interface IDiscountPolicy
+ {
+ Discount ApplyDiscount();
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Offer.cs b/PhotoStock.Sales.Domain/Offer/Offer.cs
new file mode 100644
index 0000000..ad83dd2
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Offer.cs
@@ -0,0 +1,58 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.SharedKernel;
+using System;
+using System.Collections.Generic;
+
+namespace PhotoStock.Sales.Domain.Offer
+{
+ public class Offer : ValueObject
+ {
+ private List _availableItems = new List();
+
+ public IEnumerable AvailableItems
+ {
+ get { return _availableItems; }
+ }
+
+ private List _unavailableItems = new List();
+
+ public IEnumerable UnavailableItems
+ {
+ get { return _unavailableItems; }
+ }
+
+ public Money TotalCost { get; private set;}
+ public AggregateId ClientId { get; private set; }
+ public Address ShipingAddress { get; set; }
+
+ public Offer(AggregateId clientId, List availabeItems, List unavailableItems)
+ {
+ TotalCost = Money.ZERO;
+ ClientId = clientId;
+ _availableItems = availabeItems;
+ _unavailableItems = unavailableItems;
+
+ foreach (OfferItem offerItem in availabeItems)
+ {
+ TotalCost = TotalCost + offerItem.TotalCost;
+ }
+ }
+
+ public bool SameAs(Offer seenOffer, double delta)
+ {
+ //TODO:
+ throw new NotImplementedException();
+ }
+
+ private OfferItem FindItem(AggregateId productId)
+ {
+ foreach (OfferItem item in _availableItems)
+ {
+ if (item.ProductData.ProductId.Equals(productId))
+ return item;
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/OfferItem.cs b/PhotoStock.Sales.Domain/Offer/OfferItem.cs
new file mode 100644
index 0000000..e328687
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/OfferItem.cs
@@ -0,0 +1,57 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.Sales.Domain.ProductsCatalog;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Sales.Domain.Offer
+{
+ public class OfferItem : ValueObject
+ {
+ public ProductData ProductData { get; private set; }
+ public Discount.Discount Discount { get; private set; }
+ public Money TotalCost { get; private set; }
+
+ public OfferItem(ProductData productData) : this(productData, null)
+ {
+ }
+
+ public OfferItem(ProductData productData, Discount.Discount discount)
+ {
+ ProductData = productData;
+ Discount = discount;
+
+ Money discountValue = Money.ZERO;
+ if (discount != null)
+ {
+ discountValue = discountValue - discount.Value;
+ }
+
+ TotalCost = productData.Price - discountValue;
+ }
+
+ public bool SameAs(OfferItem item, double delta)
+ {
+ if (!ProductData.Equals(item.ProductData))
+ {
+ return false;
+ }
+
+ Money max, min;
+ if (TotalCost > item.TotalCost)
+ {
+ max = TotalCost;
+ min = item.TotalCost;
+ }
+ else
+ {
+ max = item.TotalCost;
+ min = TotalCost;
+ }
+
+ Money difference = max - min;
+ Money acceptableDelta = max * (delta / 100);
+
+ return acceptableDelta > difference;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Specification/DebtorSpecification.cs b/PhotoStock.Sales.Domain/Offer/Specification/DebtorSpecification.cs
new file mode 100644
index 0000000..9706c78
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Specification/DebtorSpecification.cs
@@ -0,0 +1,35 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel.Specification;
+using PhotoStock.SharedKernel;
+using System;
+
+namespace PhotoStock.Sales.Domain.Offer.Specification
+{
+ public class DebtorSpecification : CompositeSpecification
+ {
+ private readonly Money _maxDebt;
+
+ public DebtorSpecification(Money maxDebt)
+ {
+ _maxDebt = maxDebt;
+ }
+
+ // No debt is allowed
+ public DebtorSpecification()
+ : this(Money.ZERO)
+ {
+ }
+
+ public override bool IsSatisfiedBy(Offer offer)
+ {
+ //TODO:
+ throw new NotImplementedException();
+ }
+
+ private Money LoadDebt(AggregateId clientId)
+ {
+ // TODO load debt using injected Repo/Service to this Spec
+ return Money.ZERO;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Specification/IOfferSpecificationFactory.cs b/PhotoStock.Sales.Domain/Offer/Specification/IOfferSpecificationFactory.cs
new file mode 100644
index 0000000..e3ede1b
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Specification/IOfferSpecificationFactory.cs
@@ -0,0 +1,10 @@
+using DDD.Base.SharedKernel.Specification;
+using PhotoStock.Sales.Domain.Offer;
+
+namespace PhotoStock.Sales.Application.Services
+{
+ public interface IOfferSpecificationFactory
+ {
+ ISpecification Create();
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Offer/Specification/OfferSpecificationFactory.cs b/PhotoStock.Sales.Domain/Offer/Specification/OfferSpecificationFactory.cs
new file mode 100644
index 0000000..4017532
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Offer/Specification/OfferSpecificationFactory.cs
@@ -0,0 +1,17 @@
+using DDD.Base.SharedKernel.Specification;
+using PhotoStock.Sales.Domain.Offer;
+using PhotoStock.Sales.Domain.Offer.Specification;
+
+namespace PhotoStock.Sales.Application.Services
+{
+ internal class OfferSpecificationFactory : IOfferSpecificationFactory
+ {
+ public ISpecification Create()
+ {
+ ISpecification specification
+ = new DebtorSpecification(); // not debts or max 1000 => debtors can
+
+ return specification;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/PhotoStock.Sales.Domain.csproj b/PhotoStock.Sales.Domain/PhotoStock.Sales.Domain.csproj
new file mode 100644
index 0000000..7267df3
--- /dev/null
+++ b/PhotoStock.Sales.Domain/PhotoStock.Sales.Domain.csproj
@@ -0,0 +1,90 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2230C68D-558A-463F-B3ED-427968DECB2E}
+ Library
+ Properties
+ PhotoStock.Sales.Domain
+ PhotoStock.Sales.Domain
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}
+ PhotoStock.SharedKernel
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/ProductsCatalog/IProductRepository.cs b/PhotoStock.Sales.Domain/ProductsCatalog/IProductRepository.cs
new file mode 100644
index 0000000..de98280
--- /dev/null
+++ b/PhotoStock.Sales.Domain/ProductsCatalog/IProductRepository.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Domain.ProductsCatalog
+{
+ public interface IProductRepository : IGenericRepository
+ {
+ //TODO : Query to different repository
+ List FindProductWhereBestBeforeExpiredIn(int days);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/ProductsCatalog/Product.cs b/PhotoStock.Sales.Domain/ProductsCatalog/Product.cs
new file mode 100644
index 0000000..2ecf12d
--- /dev/null
+++ b/PhotoStock.Sales.Domain/ProductsCatalog/Product.cs
@@ -0,0 +1,29 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.SharedKernel;
+using System;
+
+namespace PhotoStock.Sales.Domain.ProductsCatalog
+{
+ public class Product : AggregateRoot
+ {
+ public Money Price { get; private set; }
+
+ public string Name { get; private set; }
+
+ public ProductType ProductType { get; private set; }
+
+ private Product(AggregateId aggregateId, Money price, String name, ProductType productType)
+ : base(aggregateId)
+ {
+ Price = price;
+ Name = name;
+ ProductType = productType;
+ }
+
+ public ProductData GenerateSnapshot()
+ {
+ return new ProductData(AggregateId, Price, Name, ProductType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Properties/AssemblyInfo.cs b/PhotoStock.Sales.Domain/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..123788b
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Sales.Domain")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Sales.Domain")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2230c68d-558a-463f-b3ed-427968decb2e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Sales.Domain/Purchase/IPurchaseFactory.cs b/PhotoStock.Sales.Domain/Purchase/IPurchaseFactory.cs
new file mode 100644
index 0000000..98f859a
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Purchase/IPurchaseFactory.cs
@@ -0,0 +1,9 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Domain.Purchase
+{
+ public interface IPurchaseFactory
+ {
+ Purchase Create(AggregateId orderId, Client.Client client, Offer.Offer offer);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Purchase/IPurchaseRepository.cs b/PhotoStock.Sales.Domain/Purchase/IPurchaseRepository.cs
new file mode 100644
index 0000000..bd53157
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Purchase/IPurchaseRepository.cs
@@ -0,0 +1,8 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Domain.Purchase
+{
+ public interface IPurchaseRepository : IGenericRepository
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Purchase/Purchase.cs b/PhotoStock.Sales.Domain/Purchase/Purchase.cs
new file mode 100644
index 0000000..c0bfaf9
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Purchase/Purchase.cs
@@ -0,0 +1,35 @@
+using DDD.Base.Domain;
+using PhotoStock.SharedKernel;
+using System.Collections.Generic;
+
+namespace PhotoStock.Sales.Domain.Purchase
+{
+ public class Purchase : AggregateRoot
+ {
+ private readonly IList _items;
+ public bool IsPaid { get; private set; }
+ public AggregateId ClientId { get; private set; }
+ private Date _purchaseDate;
+ private Money _totalCost;
+
+ protected Purchase()
+ {
+ }
+
+ public Purchase(AggregateId purchaseId, AggregateId clientId, IList items, Date purchaseDate,
+ bool isPaid, Money totalCost) : base(purchaseId)
+ {
+ _items = items;
+ _purchaseDate = purchaseDate;
+ ClientId = clientId;
+ IsPaid = isPaid;
+ _totalCost = totalCost;
+ }
+
+ public void Confirm()
+ {
+ IsPaid = true;
+ EventPublisher.Publish(new PurchaseConfirmedEvent(AggregateId));
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Purchase/PurchaseConfirmedEvent.cs b/PhotoStock.Sales.Domain/Purchase/PurchaseConfirmedEvent.cs
new file mode 100644
index 0000000..4260726
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Purchase/PurchaseConfirmedEvent.cs
@@ -0,0 +1,14 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Domain.Purchase
+{
+ public class PurchaseConfirmedEvent : IDomainEvent
+ {
+ public AggregateId PurchaseId { get; set; }
+
+ public PurchaseConfirmedEvent(AggregateId purchaseId)
+ {
+ PurchaseId = purchaseId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Purchase/PurchaseFactory.cs b/PhotoStock.Sales.Domain/Purchase/PurchaseFactory.cs
new file mode 100644
index 0000000..f0342be
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Purchase/PurchaseFactory.cs
@@ -0,0 +1,47 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.Sales.Domain.Offer;
+using PhotoStock.SharedKernel;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace PhotoStock.Sales.Domain.Purchase
+{
+ public class PurchaseFactory : IPurchaseFactory
+ {
+ private IDependencyInjector _dependencyInjector;
+
+ public PurchaseFactory(IDependencyInjector dependencyInjector)
+ {
+ _dependencyInjector = dependencyInjector;
+ }
+
+ public Purchase Create(AggregateId orderId, Client.Client client, Offer.Offer offer)
+ {
+ if (!CanPurchse(client, offer.AvailableItems))
+ throw new DomainOperationException(client.AggregateId, "client can not purchase");
+
+ List items = new List(offer.AvailableItems.Count());
+ Money purchaseTotlCost = Money.ZERO;
+
+ foreach (OfferItem item in offer.AvailableItems)
+ {
+ PurchaseItem purchaseItem = new PurchaseItem(item.ProductData, item.TotalCost);
+ items.Add(purchaseItem);
+ purchaseTotlCost = purchaseTotlCost.Add(purchaseItem.TotalCost);
+ }
+
+ Purchase purchase = new Purchase(orderId, client.AggregateId,
+ items, Date.Today(), false, purchaseTotlCost);
+
+ _dependencyInjector.InjectDependencies(purchase);
+
+ return purchase;
+ }
+
+ private bool CanPurchse(Client.Client client, IEnumerable availabeItems)
+ {
+ return true; //TODO explore domain rules
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Purchase/PurchaseItem.cs b/PhotoStock.Sales.Domain/Purchase/PurchaseItem.cs
new file mode 100644
index 0000000..7629e07
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Purchase/PurchaseItem.cs
@@ -0,0 +1,23 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.Sales.Domain.ProductsCatalog;
+using PhotoStock.SharedKernel;
+
+namespace PhotoStock.Sales.Domain.Purchase
+{
+ public class PurchaseItem : Entity
+ {
+ public ProductData ProductData { get; private set; }
+ public Money TotalCost { get; private set; }
+
+ private PurchaseItem()
+ {
+ }
+
+ public PurchaseItem(ProductData productData, Money totalCost)
+ {
+ ProductData = productData;
+ TotalCost = totalCost;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Reservation/IReservationFactory.cs b/PhotoStock.Sales.Domain/Reservation/IReservationFactory.cs
new file mode 100644
index 0000000..40ea54b
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Reservation/IReservationFactory.cs
@@ -0,0 +1,7 @@
+namespace PhotoStock.Sales.Domain.Reservation
+{
+ public interface IReservationFactory
+ {
+ Reservation Create(Client.Client client);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Reservation/IReservationRepository.cs b/PhotoStock.Sales.Domain/Reservation/IReservationRepository.cs
new file mode 100644
index 0000000..96251c4
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Reservation/IReservationRepository.cs
@@ -0,0 +1,8 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Domain.Reservation
+{
+ public interface IReservationRepository : IGenericRepository
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Reservation/Reservation.cs b/PhotoStock.Sales.Domain/Reservation/Reservation.cs
new file mode 100644
index 0000000..28fb4c1
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Reservation/Reservation.cs
@@ -0,0 +1,59 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.Sales.Domain.Offer;
+using PhotoStock.Sales.Domain.Offer.Discount;
+using PhotoStock.Sales.Domain.ProductsCatalog;
+using PhotoStock.SharedKernel;
+using System;
+using System.Collections.Generic;
+
+namespace PhotoStock.Sales.Domain.Reservation
+{
+ public class Reservation : AggregateRoot
+ {
+ public enum ReservationStatus
+ {
+ OPENED,
+ CLOSED
+ };
+
+ private ReservationStatus _status;
+ private ISet _items;
+ private AggregateId _clientId;
+ private Date _createDate;
+
+ protected Reservation()
+ {
+ }
+
+ internal Reservation(AggregateId reservationId, ReservationStatus status, AggregateId clientId, Date createDate) : base(reservationId)
+ {
+ _status = status;
+ _clientId = clientId;
+ _createDate = createDate;
+ _items = new HashSet();
+ }
+
+ public void Add(Product product)
+ {
+ if (IsClosed())
+ DomainError("Reservation already closed");
+
+ //TODO:
+ }
+
+ public bool IsClosed()
+ {
+ return _status == ReservationStatus.CLOSED;
+ }
+
+ public void Close()
+ {
+ if (IsClosed())
+ {
+ DomainError("Reservation is already closed");
+ }
+ _status = ReservationStatus.CLOSED;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Reservation/ReservationCreatedEvent.cs b/PhotoStock.Sales.Domain/Reservation/ReservationCreatedEvent.cs
new file mode 100644
index 0000000..1597a9b
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Reservation/ReservationCreatedEvent.cs
@@ -0,0 +1,14 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Sales.Domain.Reservation
+{
+ public class ReservationCreatedEvent : IDomainEvent
+ {
+ public AggregateId AggregateId { get; set; }
+
+ public ReservationCreatedEvent(AggregateId aggregateId)
+ {
+ AggregateId = aggregateId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Domain/Reservation/ReservationFactory.cs b/PhotoStock.Sales.Domain/Reservation/ReservationFactory.cs
new file mode 100644
index 0000000..cda8679
--- /dev/null
+++ b/PhotoStock.Sales.Domain/Reservation/ReservationFactory.cs
@@ -0,0 +1,16 @@
+using DDD.Base.Domain;
+using DDD.Base.SharedKernel;
+using PhotoStock.SharedKernel;
+using System;
+
+namespace PhotoStock.Sales.Domain.Reservation
+{
+ public class ReservationFactory : IReservationFactory
+ {
+ public Reservation Create(Client.Client client)
+ {
+ //TODO:
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Infrastructure/ClientRepository.cs b/PhotoStock.Sales.Infrastructure/ClientRepository.cs
new file mode 100644
index 0000000..16ea03f
--- /dev/null
+++ b/PhotoStock.Sales.Infrastructure/ClientRepository.cs
@@ -0,0 +1,13 @@
+using DDD.Base.Domain;
+using DDD.Infrastructure;
+using NHibernate;
+
+namespace PhotoStock.Sales.Domain.Client
+{
+ public class ClientRepository : GenericRepository, IClientRepository
+ {
+ public ClientRepository(ISession session, IDependencyInjector dependencyInjector) : base(session, dependencyInjector)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Infrastructure/EventPublisher.cs b/PhotoStock.Sales.Infrastructure/EventPublisher.cs
new file mode 100644
index 0000000..b09e2c8
--- /dev/null
+++ b/PhotoStock.Sales.Infrastructure/EventPublisher.cs
@@ -0,0 +1,50 @@
+using DDD.Base.Domain;
+using PhotoStock.Sales.Contract.Events;
+using PhotoStock.Sales.Domain.Client;
+using PhotoStock.Sales.Domain.Purchase;
+using PhotoStock.Sales.Domain.Reservation;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Photostock.Sales.Infrastructure
+{
+ public class EventPublisher : IDomainEventPublisher
+ {
+ private ISystemEventPublisher _systemEventPublisher;
+ private IPurchaseRepository _purchaseRepository;
+ private IDictionary> _handlers = new Dictionary>();
+ private IClientRepository _clientRepository;
+
+ public EventPublisher(ISystemEventPublisher systemEventPublisher, IClientRepository clientRepository, IPurchaseRepository purchaseRepository)
+ {
+ _systemEventPublisher = systemEventPublisher;
+ _clientRepository = clientRepository;
+ _purchaseRepository = purchaseRepository;
+ _handlers[typeof(ReservationCreatedEvent)] = f => ReservationCreatedHandler(f as ReservationCreatedEvent);
+ _handlers[typeof(PurchaseConfirmedEvent)] = f => PurchaseConfirmedHandler(f as PurchaseConfirmedEvent);
+ }
+
+ private ISystemEvent PurchaseConfirmedHandler(PurchaseConfirmedEvent purchaseConfirmedEvent)
+ {
+ Purchase purchase = _purchaseRepository.Load(purchaseConfirmedEvent.PurchaseId);
+ OrderConfirmedEventBuilder builder = new OrderConfirmedEventBuilder(_clientRepository);
+
+ //TODO:
+ throw new NotImplementedException();
+ }
+
+ private ISystemEvent ReservationCreatedHandler(ReservationCreatedEvent f)
+ {
+ return new OrderCreatedEvent(f.AggregateId);
+ }
+
+ public void Publish(T domainEvent) where T : IDomainEvent
+ {
+ ISystemEvent result = _handlers[typeof(T)](domainEvent);
+ _systemEventPublisher.Publish(result);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Infrastructure/FakeSession.cs b/PhotoStock.Sales.Infrastructure/FakeSession.cs
new file mode 100644
index 0000000..3dc5bff
--- /dev/null
+++ b/PhotoStock.Sales.Infrastructure/FakeSession.cs
@@ -0,0 +1,424 @@
+using NHibernate;
+using NHibernate.Engine;
+using NHibernate.Stat;
+using NHibernate.Type;
+using System;
+using System.Data;
+using System.Linq.Expressions;
+
+namespace PhotoStock.Sales.Application
+{
+ public class FakeSession : ISession
+ {
+ public void Dispose()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Flush()
+ {
+ throw new NotImplementedException();
+ }
+
+ public IDbConnection Disconnect()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Reconnect()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Reconnect(IDbConnection connection)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IDbConnection Close()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void CancelQuery()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool IsDirty()
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool IsReadOnly(object entityOrProxy)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetReadOnly(object entityOrProxy, bool readOnly)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetIdentifier(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool Contains(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Evict(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Load(Type theType, object id, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Load(string entityName, object id, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Load(Type theType, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T Load(object id, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T Load(object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Load(string entityName, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Load(object obj, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Replicate(object obj, ReplicationMode replicationMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Replicate(string entityName, object obj, ReplicationMode replicationMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Save(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Save(object obj, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Save(string entityName, object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Save(string entityName, object obj, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SaveOrUpdate(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SaveOrUpdate(string entityName, object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SaveOrUpdate(string entityName, object obj, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Update(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Update(object obj, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Update(string entityName, object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Update(string entityName, object obj, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Merge(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Merge(string entityName, object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T Merge(T entity) where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public T Merge(string entityName, T entity) where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Persist(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Persist(string entityName, object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Delete(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Delete(string entityName, object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int Delete(string query)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int Delete(string query, object value, IType type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public int Delete(string query, object[] values, IType[] types)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Lock(object obj, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Lock(string entityName, object obj, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Refresh(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Refresh(object obj, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public LockMode GetCurrentLockMode(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ITransaction BeginTransaction()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ITransaction BeginTransaction(IsolationLevel isolationLevel)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICriteria CreateCriteria() where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICriteria CreateCriteria(string alias) where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICriteria CreateCriteria(Type persistentClass)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICriteria CreateCriteria(Type persistentClass, string alias)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICriteria CreateCriteria(string entityName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ICriteria CreateCriteria(string entityName, string alias)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQueryOver QueryOver() where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQueryOver QueryOver(Expression> alias) where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQueryOver QueryOver(string entityName) where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQueryOver QueryOver(string entityName, Expression> alias) where T : class
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQuery CreateQuery(string queryString)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQuery CreateFilter(object collection, string queryString)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IQuery GetNamedQuery(string queryName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ISQLQuery CreateSQLQuery(string queryString)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Clear()
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Get(Type clazz, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Get(Type clazz, object id, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object Get(string entityName, object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T Get(object id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T Get(object id, LockMode lockMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetEntityName(object obj)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IFilter EnableFilter(string filterName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IFilter GetEnabledFilter(string filterName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void DisableFilter(string filterName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IMultiQuery CreateMultiQuery()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ISession SetBatchSize(int batchSize)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ISessionImplementor GetSessionImplementation()
+ {
+ throw new NotImplementedException();
+ }
+
+ public IMultiCriteria CreateMultiCriteria()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ISession GetSession(EntityMode entityMode)
+ {
+ throw new NotImplementedException();
+ }
+
+ public EntityMode ActiveEntityMode { get; private set; }
+ public FlushMode FlushMode { get; set; }
+ public CacheMode CacheMode { get; set; }
+ public ISessionFactory SessionFactory { get; private set; }
+ public IDbConnection Connection { get; private set; }
+ public bool IsOpen { get; private set; }
+ public bool IsConnected { get; private set; }
+ public bool DefaultReadOnly { get; set; }
+ public ITransaction Transaction { get; private set; }
+ public ISessionStatistics Statistics { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Infrastructure/OrderConfirmedEventBuilder.cs b/PhotoStock.Sales.Infrastructure/OrderConfirmedEventBuilder.cs
new file mode 100644
index 0000000..8c94acb
--- /dev/null
+++ b/PhotoStock.Sales.Infrastructure/OrderConfirmedEventBuilder.cs
@@ -0,0 +1,27 @@
+using DDD.Base.Domain;
+using PhotoStock.Sales.Contract.Events;
+using PhotoStock.Sales.Domain.Client;
+using PhotoStock.Sales.Domain.Purchase;
+using PhotoStock.SharedKernel;
+using System.Collections.Generic;
+
+namespace Photostock.Sales.Infrastructure
+{
+ internal class OrderConfirmedEventBuilder
+ {
+ private AggregateId _orderId;
+ private ClientData _clientData;
+ private IClientRepository _clientRepository;
+ private List _items = new List();
+
+ public OrderConfirmedEventBuilder(IClientRepository clientRepository)
+ {
+ _clientRepository = clientRepository;
+ }
+
+ public ISystemEvent Build()
+ {
+ return new OrderConfirmedEvent(_orderId, _clientData, _items);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Infrastructure/Photostock.Sales.Infrastructure.csproj b/PhotoStock.Sales.Infrastructure/Photostock.Sales.Infrastructure.csproj
new file mode 100644
index 0000000..70e327a
--- /dev/null
+++ b/PhotoStock.Sales.Infrastructure/Photostock.Sales.Infrastructure.csproj
@@ -0,0 +1,94 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {42D9D95B-3F19-46E3-9CCB-B9276A465E13}
+ Library
+ Properties
+ Photostock.Sales.Infrastructure
+ Photostock.Sales.Infrastructure
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll
+ True
+
+
+ ..\packages\NHibernate.4.0.4.4000\lib\net40\NHibernate.dll
+ True
+
+
+ ..\packages\NUnit.3.2.1\lib\net45\nunit.framework.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}
+ DDD.Infrastructure
+
+
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ PhotoStock.Sales.Contract
+
+
+ {2230C68D-558A-463F-B3ED-427968DECB2E}
+ PhotoStock.Sales.Domain
+
+
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}
+ PhotoStock.SharedKernel
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Sales.Infrastructure/Properties/AssemblyInfo.cs b/PhotoStock.Sales.Infrastructure/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d2c3111
--- /dev/null
+++ b/PhotoStock.Sales.Infrastructure/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Photostock.Sales.Infrastructure")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Photostock.Sales.Infrastructure")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("42d9d95b-3f19-46e3-9ccb-b9276a465e13")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Sales.Infrastructure/packages.config b/PhotoStock.Sales.Infrastructure/packages.config
new file mode 100644
index 0000000..4d3cf39
--- /dev/null
+++ b/PhotoStock.Sales.Infrastructure/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Sales.Query/Offer/IOfferFinder.cs b/PhotoStock.Sales.Query/Offer/IOfferFinder.cs
new file mode 100644
index 0000000..dd0e9b9
--- /dev/null
+++ b/PhotoStock.Sales.Query/Offer/IOfferFinder.cs
@@ -0,0 +1,10 @@
+using CQRS.Base.Query;
+using System.Collections.Generic;
+
+namespace PhotoStock.Sales.Query.Offer
+{
+ public interface IProductFinder
+ {
+ PaginatedResult GetPage(OfferQuery query);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Query/Offer/OfferQuery.cs b/PhotoStock.Sales.Query/Offer/OfferQuery.cs
new file mode 100644
index 0000000..39086fd
--- /dev/null
+++ b/PhotoStock.Sales.Query/Offer/OfferQuery.cs
@@ -0,0 +1,6 @@
+namespace PhotoStock.Sales.Query.Offer
+{
+ public class OfferQuery
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Query/Offer/OfferedProductDto.cs b/PhotoStock.Sales.Query/Offer/OfferedProductDto.cs
new file mode 100644
index 0000000..c96b166
--- /dev/null
+++ b/PhotoStock.Sales.Query/Offer/OfferedProductDto.cs
@@ -0,0 +1,6 @@
+namespace PhotoStock.Sales.Query.Offer
+{
+ public class ProductDto
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Sales.Query/PhotoStock.Sales.Query.csproj b/PhotoStock.Sales.Query/PhotoStock.Sales.Query.csproj
new file mode 100644
index 0000000..2910149
--- /dev/null
+++ b/PhotoStock.Sales.Query/PhotoStock.Sales.Query.csproj
@@ -0,0 +1,67 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {7BFE16B3-7692-4CE3-8237-1F84CBA62304}
+ Library
+ Properties
+ PhotoStock.Sales.Query
+ PhotoStock.Sales.Query
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}
+ CQRS.Base
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Sales.Query/Properties/AssemblyInfo.cs b/PhotoStock.Sales.Query/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d30723b
--- /dev/null
+++ b/PhotoStock.Sales.Query/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Sales.Query")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Sales.Query")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7bfe16b3-7692-4ce3-8237-1f84cba62304")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.SharedKernel/ClientData.cs b/PhotoStock.SharedKernel/ClientData.cs
new file mode 100644
index 0000000..67d49e5
--- /dev/null
+++ b/PhotoStock.SharedKernel/ClientData.cs
@@ -0,0 +1,22 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.SharedKernel
+{
+ public class ClientData : ValueObject
+ {
+ public ClientData(AggregateId aggregateId, string name)
+ {
+ AggregateId = aggregateId;
+ Name = name;
+ }
+
+ public AggregateId AggregateId { get; private set; }
+ public string Name { get; private set; }
+ public TaxNumber TaxNumber { get; set; }
+ public Address Address { get; set; }
+ }
+
+ public class Address : ValueObject
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.SharedKernel/Date.cs b/PhotoStock.SharedKernel/Date.cs
new file mode 100644
index 0000000..0498497
--- /dev/null
+++ b/PhotoStock.SharedKernel/Date.cs
@@ -0,0 +1,20 @@
+using System;
+using DDD.Base.Domain;
+
+namespace PhotoStock.SharedKernel
+{
+ public class Date : ValueObject
+ {
+ private readonly DateTime _date;
+
+ private Date(DateTime date)
+ {
+ _date = date.Date;
+ }
+
+ public static Date Today()
+ {
+ return new Date(DateTime.Today);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.SharedKernel/Money.cs b/PhotoStock.SharedKernel/Money.cs
new file mode 100644
index 0000000..e7a5e31
--- /dev/null
+++ b/PhotoStock.SharedKernel/Money.cs
@@ -0,0 +1,85 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.SharedKernel
+{
+ public class Money : ValueObject
+ {
+ private decimal _amount;
+ public static Money ZERO = 0;
+
+ private Money(decimal amount)
+ {
+ _amount = amount;
+ }
+
+ private Money(double amount)
+ {
+ _amount = (decimal)amount;
+ }
+
+ public static Money operator -(Money x)
+ {
+ return new Money(-x._amount);
+ }
+
+ public static Money operator *(Money money, decimal value)
+ {
+ return new Money(money._amount * value);
+ }
+
+ public static Money operator *(Money money, double value)
+ {
+ return new Money((decimal)((double)money._amount * value));
+ }
+
+ public static Money operator *(double value, Money money)
+ {
+ return new Money((decimal)((double)money._amount * value));
+ }
+
+ public static Money operator *(decimal value, Money money)
+ {
+ return new Money(money._amount * value);
+ }
+
+ public static Money operator +(Money money, Money value)
+ {
+ return new Money(money._amount + value._amount);
+ }
+
+ public static Money operator -(Money money, Money value)
+ {
+ return new Money(money._amount - value._amount);
+ }
+
+ public static bool operator >(Money money, Money value)
+ {
+ return money._amount > value._amount;
+ }
+
+ public static bool operator >=(Money money, Money value)
+ {
+ return money._amount >= value._amount;
+ }
+
+ public static bool operator <(Money money, Money value)
+ {
+ return money._amount < value._amount;
+ }
+
+ public static bool operator <=(Money money, Money value)
+ {
+ return money._amount <= value._amount;
+ }
+
+ public static implicit operator Money(decimal value)
+ {
+ return new Money(value);
+ }
+
+ public Money Add(Money net)
+ {
+ return new Money(_amount + net._amount);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.SharedKernel/PhotoStock.SharedKernel.csproj b/PhotoStock.SharedKernel/PhotoStock.SharedKernel.csproj
new file mode 100644
index 0000000..42515b8
--- /dev/null
+++ b/PhotoStock.SharedKernel/PhotoStock.SharedKernel.csproj
@@ -0,0 +1,65 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}
+ Library
+ Properties
+ PhotoStock.SharedKernel
+ PhotoStock.SharedKernel
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.SharedKernel/ProductData.cs b/PhotoStock.SharedKernel/ProductData.cs
new file mode 100644
index 0000000..2715a6d
--- /dev/null
+++ b/PhotoStock.SharedKernel/ProductData.cs
@@ -0,0 +1,21 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.SharedKernel
+{
+ public class ProductData
+ {
+ public ProductData(AggregateId productId, Money price, string name, ProductType productType)
+ {
+ ProductId = productId;
+ Price = price;
+ Name = name;
+ ProductType = productType;
+ }
+
+ public ProductType Type { get; set; }
+ public AggregateId ProductId { get; set; }
+ public Money Price { get; set; }
+ public string Name { get; set; }
+ public ProductType ProductType { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.SharedKernel/ProductType.cs b/PhotoStock.SharedKernel/ProductType.cs
new file mode 100644
index 0000000..a20bf7a
--- /dev/null
+++ b/PhotoStock.SharedKernel/ProductType.cs
@@ -0,0 +1,8 @@
+namespace PhotoStock.SharedKernel
+{
+ public enum ProductType
+ {
+ Printed,
+ Electronic
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.SharedKernel/Properties/AssemblyInfo.cs b/PhotoStock.SharedKernel/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..57f7b03
--- /dev/null
+++ b/PhotoStock.SharedKernel/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.SharedKernel")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.SharedKernel")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("266ff480-2b3a-40c5-b01c-721c9a4d79d3")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.SharedKernel/TaxNumber.cs b/PhotoStock.SharedKernel/TaxNumber.cs
new file mode 100644
index 0000000..20d2441
--- /dev/null
+++ b/PhotoStock.SharedKernel/TaxNumber.cs
@@ -0,0 +1,9 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.SharedKernel
+{
+ public class TaxNumber : ValueObject
+ {
+ //TODO: implementation
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Application/PhotoStock.Shipping.Application.csproj b/PhotoStock.Shipping.Application/PhotoStock.Shipping.Application.csproj
new file mode 100644
index 0000000..447ed50
--- /dev/null
+++ b/PhotoStock.Shipping.Application/PhotoStock.Shipping.Application.csproj
@@ -0,0 +1,79 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {DB22ADE0-E49E-4B7E-9329-5AEA5F82072C}
+ Library
+ Properties
+ PhotoStock.Shipping.Application
+ PhotoStock.Shipping.Application
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}
+ CQRS.Base
+
+
+ {f8d43559-8792-498b-ab51-211ca04cb4df}
+ DDD.Base
+
+
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}
+ PhotoStock.Sales.Contract
+
+
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}
+ PhotoStock.Shipping.Contract
+
+
+ {B49CABB5-36C5-4028-BA42-0F3E0B94E33F}
+ PhotoStock.Shipping.Domain
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Application/Properties/AssemblyInfo.cs b/PhotoStock.Shipping.Application/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b596752
--- /dev/null
+++ b/PhotoStock.Shipping.Application/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Shipping.Application")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Shipping.Application")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("db22ade0-e49e-4b7e-9329-5aea5f82072c")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Shipping.Contract/Commands/DeliverShipmentCommand.cs b/PhotoStock.Shipping.Contract/Commands/DeliverShipmentCommand.cs
new file mode 100644
index 0000000..fde7d10
--- /dev/null
+++ b/PhotoStock.Shipping.Contract/Commands/DeliverShipmentCommand.cs
@@ -0,0 +1,14 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Shipping.Contract.Commands
+{
+ public class DeliverShipmentCommand
+ {
+ public AggregateId ShipmentId { get; private set; }
+
+ public DeliverShipmentCommand(AggregateId shipmentId)
+ {
+ ShipmentId = shipmentId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Contract/Commands/SendShipmentCommand.cs b/PhotoStock.Shipping.Contract/Commands/SendShipmentCommand.cs
new file mode 100644
index 0000000..9c0c97b
--- /dev/null
+++ b/PhotoStock.Shipping.Contract/Commands/SendShipmentCommand.cs
@@ -0,0 +1,14 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Shipping.Contract.Commands
+{
+ public class SendShipmentCommand
+ {
+ public AggregateId OrderId { get; set; }
+
+ public SendShipmentCommand(AggregateId orderId)
+ {
+ OrderId = orderId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Contract/Events/OrderShippedEvent.cs b/PhotoStock.Shipping.Contract/Events/OrderShippedEvent.cs
new file mode 100644
index 0000000..1d13277
--- /dev/null
+++ b/PhotoStock.Shipping.Contract/Events/OrderShippedEvent.cs
@@ -0,0 +1,16 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Shipping.Contract.Events
+{
+ public class OrderShippedEvent : IDomainEvent
+ {
+ public AggregateId OrderId { get; private set; }
+ public AggregateId ShipmentId { get; private set; }
+
+ public OrderShippedEvent(AggregateId orderId, AggregateId shipmentId)
+ {
+ OrderId = orderId;
+ ShipmentId = shipmentId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Contract/PhotoStock.Shipping.Contract.csproj b/PhotoStock.Shipping.Contract/PhotoStock.Shipping.Contract.csproj
new file mode 100644
index 0000000..1868278
--- /dev/null
+++ b/PhotoStock.Shipping.Contract/PhotoStock.Shipping.Contract.csproj
@@ -0,0 +1,62 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}
+ Library
+ Properties
+ PhotoStock.Shipping.Contract
+ PhotoStock.Shipping.Contract
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Contract/Properties/AssemblyInfo.cs b/PhotoStock.Shipping.Contract/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c105457
--- /dev/null
+++ b/PhotoStock.Shipping.Contract/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Shipping.Contract")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Shipping.Contract")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1ff64b1a-907e-4056-82a5-67b3efd45c78")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Shipping.Domain/IShipmentFactory.cs b/PhotoStock.Shipping.Domain/IShipmentFactory.cs
new file mode 100644
index 0000000..a8fb515
--- /dev/null
+++ b/PhotoStock.Shipping.Domain/IShipmentFactory.cs
@@ -0,0 +1,9 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Shipping.Domain
+{
+ public interface IShipmentFactory
+ {
+ Shipment CreateShipment(AggregateId orderId);
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Domain/IShipmentRepository.cs b/PhotoStock.Shipping.Domain/IShipmentRepository.cs
new file mode 100644
index 0000000..355a9dc
--- /dev/null
+++ b/PhotoStock.Shipping.Domain/IShipmentRepository.cs
@@ -0,0 +1,8 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Shipping.Domain
+{
+ public interface IShipmentRepository : IGenericRepository
+ {
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Domain/PhotoStock.Shipping.Domain.csproj b/PhotoStock.Shipping.Domain/PhotoStock.Shipping.Domain.csproj
new file mode 100644
index 0000000..570fbee
--- /dev/null
+++ b/PhotoStock.Shipping.Domain/PhotoStock.Shipping.Domain.csproj
@@ -0,0 +1,68 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B49CABB5-36C5-4028-BA42-0F3E0B94E33F}
+ Library
+ Properties
+ PhotoStock.Shipping.Domain
+ PhotoStock.Shipping.Domain
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}
+ PhotoStock.Shipping.Contract
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Domain/Properties/AssemblyInfo.cs b/PhotoStock.Shipping.Domain/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2946cc3
--- /dev/null
+++ b/PhotoStock.Shipping.Domain/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Shipping.Domain")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Shipping.Domain")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b49cabb5-36c5-4028-ba42-0f3e0b94e33f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Shipping.Domain/Shipment.cs b/PhotoStock.Shipping.Domain/Shipment.cs
new file mode 100644
index 0000000..6fe8152
--- /dev/null
+++ b/PhotoStock.Shipping.Domain/Shipment.cs
@@ -0,0 +1,37 @@
+using DDD.Base.Domain;
+using DDD.Base.Domain.Exceptions;
+using PhotoStock.Shipping.Contract.Events;
+
+namespace PhotoStock.Shipping.Domain
+{
+ public class Shipment : AggregateRoot
+ {
+ public AggregateId OrderId { get; private set; }
+
+ public ShippingStatus ShipmentStatus { get; private set; }
+
+ private Shipment()
+ {
+ }
+
+ public Shipment(AggregateId orderId)
+ {
+ OrderId = orderId;
+ ShipmentStatus = ShippingStatus.WAITING;
+ }
+
+ /**
+ * Shipment has been sent to the customer.
+ */
+
+ public void Ship()
+ {
+ if (ShipmentStatus != ShippingStatus.WAITING)
+ {
+ throw new IllegalStateException("Cannot ship in status " + ShipmentStatus);
+ }
+ ShipmentStatus = ShippingStatus.SENT;
+ EventPublisher.Publish(new OrderShippedEvent(OrderId, AggregateId));
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Domain/ShipmentFactory.cs b/PhotoStock.Shipping.Domain/ShipmentFactory.cs
new file mode 100644
index 0000000..8c4b63b
--- /dev/null
+++ b/PhotoStock.Shipping.Domain/ShipmentFactory.cs
@@ -0,0 +1,23 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.Shipping.Domain
+{
+ public class ShipmentFactory : IShipmentFactory
+ {
+ private IDependencyInjector _dependencyInjector;
+
+ public ShipmentFactory(IDependencyInjector dependencyInjector)
+ {
+ _dependencyInjector = dependencyInjector;
+ }
+
+ public Shipment CreateShipment(AggregateId orderId)
+ {
+ Shipment shipment = new Shipment(orderId);
+
+ _dependencyInjector.InjectDependencies(shipment);
+
+ return shipment;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Shipping.Domain/ShippingStatus.cs b/PhotoStock.Shipping.Domain/ShippingStatus.cs
new file mode 100644
index 0000000..fc18c10
--- /dev/null
+++ b/PhotoStock.Shipping.Domain/ShippingStatus.cs
@@ -0,0 +1,10 @@
+namespace PhotoStock.Shipping.Domain
+{
+
+ public enum ShippingStatus
+ {
+ WAITING,
+ SENT,
+ DELIVERED
+ }
+}
diff --git a/PhotoStock.System/ISystemContext.cs b/PhotoStock.System/ISystemContext.cs
new file mode 100644
index 0000000..ecff134
--- /dev/null
+++ b/PhotoStock.System/ISystemContext.cs
@@ -0,0 +1,7 @@
+namespace PhotoStock.System
+{
+ public interface ISystemContext
+ {
+ SystemUser SystemUser { get; }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.System/PhotoStock.System.csproj b/PhotoStock.System/PhotoStock.System.csproj
new file mode 100644
index 0000000..da1eabf
--- /dev/null
+++ b/PhotoStock.System/PhotoStock.System.csproj
@@ -0,0 +1,62 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2FC58C62-FE65-46C7-989E-180C2B8E41EE}
+ Library
+ Properties
+ PhotoStock.System
+ PhotoStock.System
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}
+ DDD.Base
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.System/Properties/AssemblyInfo.cs b/PhotoStock.System/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1d050ec
--- /dev/null
+++ b/PhotoStock.System/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.System")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.System")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2fc58c62-fe65-46c7-989e-180c2b8e41ee")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.System/SystemContext.cs b/PhotoStock.System/SystemContext.cs
new file mode 100644
index 0000000..7347602
--- /dev/null
+++ b/PhotoStock.System/SystemContext.cs
@@ -0,0 +1,15 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.System
+{
+ internal class SystemContext : ISystemContext
+ {
+ public SystemUser SystemUser
+ {
+ get
+ {
+ return new SystemUser(new AggregateId("1")); //TODO introduce security integration
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.System/SystemUser.cs b/PhotoStock.System/SystemUser.cs
new file mode 100644
index 0000000..b7ec332
--- /dev/null
+++ b/PhotoStock.System/SystemUser.cs
@@ -0,0 +1,19 @@
+using DDD.Base.Domain;
+
+namespace PhotoStock.System
+{
+ public class SystemUser
+ {
+ public AggregateId ClientId { get; private set; }
+
+ internal SystemUser(AggregateId clientId)
+ {
+ ClientId = clientId;
+ }
+
+ public bool IsLoogedIn()
+ {
+ return ClientId != null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Tests/Class1.cs b/PhotoStock.Tests/Class1.cs
new file mode 100644
index 0000000..076f643
--- /dev/null
+++ b/PhotoStock.Tests/Class1.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PhotoStock.Tests
+{
+ public class OrderingService
+ {
+ public void NewOrder(ClientId clientId)
+ {
+ Order o = _orderFactory.Create(clientId);
+
+ _historyService.Add
+ OrderHistory
+ }
+ }
+}
\ No newline at end of file
diff --git a/PhotoStock.Tests/PhotoStock.Tests.csproj b/PhotoStock.Tests/PhotoStock.Tests.csproj
new file mode 100644
index 0000000..625be74
--- /dev/null
+++ b/PhotoStock.Tests/PhotoStock.Tests.csproj
@@ -0,0 +1,65 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {67F68401-9A9D-48FD-BB9E-A4DAF35CCA65}
+ Library
+ Properties
+ PhotoStock.Tests
+ PhotoStock.Tests
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.Tests/Properties/AssemblyInfo.cs b/PhotoStock.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..084590e
--- /dev/null
+++ b/PhotoStock.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PhotoStock.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PhotoStock.Tests")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("67f68401-9a9d-48fd-bb9e-a4daf35cca65")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PhotoStock.Tests/packages.config b/PhotoStock.Tests/packages.config
new file mode 100644
index 0000000..f8429b5
--- /dev/null
+++ b/PhotoStock.Tests/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/PhotoStock.sln b/PhotoStock.sln
new file mode 100644
index 0000000..9f3d45c
--- /dev/null
+++ b/PhotoStock.sln
@@ -0,0 +1,158 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Tests", "PhotoStock.Tests\PhotoStock.Tests.csproj", "{67F68401-9A9D-48FD-BB9E-A4DAF35CCA65}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Sales.Domain", "PhotoStock.Sales.Domain\PhotoStock.Sales.Domain.csproj", "{2230C68D-558A-463F-B3ED-427968DECB2E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Sales.Query", "PhotoStock.Sales.Query\PhotoStock.Sales.Query.csproj", "{7BFE16B3-7692-4CE3-8237-1F84CBA62304}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DDD.Base", "DDD.Base\DDD.Base.csproj", "{F8D43559-8792-498B-AB51-211CA04CB4DF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CQRS.Base", "CQRS.Base\CQRS.Base.csproj", "{7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DDD.Infrastructure", "DDD.Infrastructure\DDD.Infrastructure.csproj", "{1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Base", "Base", "{A0F7DF3D-4B23-4243-9834-E35FBC15C9A8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sales", "Sales", "{C8607D23-999C-46EE-946A-85C6CF69746F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shipping", "Shipping", "{0D8B3E81-E824-4CE0-A516-87C4ECB59F52}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Sales.Application", "PhotoStock.Sales.Application\PhotoStock.Sales.Application.csproj", "{502D416A-D97E-46F6-B47F-85AB0BFDCD3A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.System", "PhotoStock.System\PhotoStock.System.csproj", "{2FC58C62-FE65-46C7-989E-180C2B8E41EE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Shipping.Application", "PhotoStock.Shipping.Application\PhotoStock.Shipping.Application.csproj", "{DB22ADE0-E49E-4B7E-9329-5AEA5F82072C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Shipping.Domain", "PhotoStock.Shipping.Domain\PhotoStock.Shipping.Domain.csproj", "{B49CABB5-36C5-4028-BA42-0F3E0B94E33F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Shipping.Contract", "PhotoStock.Shipping.Contract\PhotoStock.Shipping.Contract.csproj", "{1FF64B1A-907E-4056-82A5-67B3EFD45C78}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Sales.Contract", "PhotoStock.Sales.Contract\PhotoStock.Sales.Contract.csproj", "{EA7D831A-03D1-4A08-805C-3E450EA024BC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.SharedKernel", "PhotoStock.SharedKernel\PhotoStock.SharedKernel.csproj", "{266FF480-2B3A-40C5-B01C-721C9A4D79D3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Photostock.Sales.Infrastructure", "Photostock.Sales.Infrastructure\Photostock.Sales.Infrastructure.csproj", "{42D9D95B-3F19-46E3-9CCB-B9276A465E13}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Invoicing", "Invoicing", "{80ACDAD5-3FE5-4559-B11F-5F7CF18FF85C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Invoicing.Domain", "PhotoStock.Invoicing.Domain\PhotoStock.Invoicing.Domain.csproj", "{F686EDF5-2B9C-4DE1-B197-785B38BE4B97}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Invoicing.Application", "PhotoStock.Invoicing.Application\PhotoStock.Invoicing.Application.csproj", "{91D4A03B-CCE7-4A9A-AA80-626251967A2B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.Invoicing.Contract", "PhotoStock.Invoicing.Contract\PhotoStock.Invoicing.Contract.csproj", "{265016F3-AE52-4167-926A-52924366E7DD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BusinessProcess", "BusinessProcess", "{EA8DA886-D082-4565-95FA-7E70248260B7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.BusinessProcess.Tests", "PhotoStock.BusinessProcess.Tests\PhotoStock.BusinessProcess.Tests.csproj", "{5C0936A5-3185-44C5-9B6B-FEB039CFB6F7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoStock.BusinessProcess", "PhotoStock.BusinessProcess\PhotoStock.BusinessProcess.csproj", "{6B0EA748-FC9A-467B-B3D4-A2A025EEBB29}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {67F68401-9A9D-48FD-BB9E-A4DAF35CCA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {67F68401-9A9D-48FD-BB9E-A4DAF35CCA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {67F68401-9A9D-48FD-BB9E-A4DAF35CCA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {67F68401-9A9D-48FD-BB9E-A4DAF35CCA65}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2230C68D-558A-463F-B3ED-427968DECB2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2230C68D-558A-463F-B3ED-427968DECB2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2230C68D-558A-463F-B3ED-427968DECB2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2230C68D-558A-463F-B3ED-427968DECB2E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7BFE16B3-7692-4CE3-8237-1F84CBA62304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7BFE16B3-7692-4CE3-8237-1F84CBA62304}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7BFE16B3-7692-4CE3-8237-1F84CBA62304}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7BFE16B3-7692-4CE3-8237-1F84CBA62304}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8D43559-8792-498B-AB51-211CA04CB4DF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {502D416A-D97E-46F6-B47F-85AB0BFDCD3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {502D416A-D97E-46F6-B47F-85AB0BFDCD3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {502D416A-D97E-46F6-B47F-85AB0BFDCD3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {502D416A-D97E-46F6-B47F-85AB0BFDCD3A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2FC58C62-FE65-46C7-989E-180C2B8E41EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2FC58C62-FE65-46C7-989E-180C2B8E41EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2FC58C62-FE65-46C7-989E-180C2B8E41EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2FC58C62-FE65-46C7-989E-180C2B8E41EE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DB22ADE0-E49E-4B7E-9329-5AEA5F82072C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DB22ADE0-E49E-4B7E-9329-5AEA5F82072C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DB22ADE0-E49E-4B7E-9329-5AEA5F82072C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DB22ADE0-E49E-4B7E-9329-5AEA5F82072C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B49CABB5-36C5-4028-BA42-0F3E0B94E33F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B49CABB5-36C5-4028-BA42-0F3E0B94E33F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B49CABB5-36C5-4028-BA42-0F3E0B94E33F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B49CABB5-36C5-4028-BA42-0F3E0B94E33F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {266FF480-2B3A-40C5-B01C-721C9A4D79D3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {42D9D95B-3F19-46E3-9CCB-B9276A465E13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {42D9D95B-3F19-46E3-9CCB-B9276A465E13}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {42D9D95B-3F19-46E3-9CCB-B9276A465E13}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {42D9D95B-3F19-46E3-9CCB-B9276A465E13}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F686EDF5-2B9C-4DE1-B197-785B38BE4B97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F686EDF5-2B9C-4DE1-B197-785B38BE4B97}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F686EDF5-2B9C-4DE1-B197-785B38BE4B97}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F686EDF5-2B9C-4DE1-B197-785B38BE4B97}.Release|Any CPU.Build.0 = Release|Any CPU
+ {91D4A03B-CCE7-4A9A-AA80-626251967A2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {91D4A03B-CCE7-4A9A-AA80-626251967A2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {91D4A03B-CCE7-4A9A-AA80-626251967A2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {91D4A03B-CCE7-4A9A-AA80-626251967A2B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {265016F3-AE52-4167-926A-52924366E7DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {265016F3-AE52-4167-926A-52924366E7DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {265016F3-AE52-4167-926A-52924366E7DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {265016F3-AE52-4167-926A-52924366E7DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5C0936A5-3185-44C5-9B6B-FEB039CFB6F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5C0936A5-3185-44C5-9B6B-FEB039CFB6F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5C0936A5-3185-44C5-9B6B-FEB039CFB6F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5C0936A5-3185-44C5-9B6B-FEB039CFB6F7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6B0EA748-FC9A-467B-B3D4-A2A025EEBB29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6B0EA748-FC9A-467B-B3D4-A2A025EEBB29}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6B0EA748-FC9A-467B-B3D4-A2A025EEBB29}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6B0EA748-FC9A-467B-B3D4-A2A025EEBB29}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {2230C68D-558A-463F-B3ED-427968DECB2E} = {C8607D23-999C-46EE-946A-85C6CF69746F}
+ {7BFE16B3-7692-4CE3-8237-1F84CBA62304} = {C8607D23-999C-46EE-946A-85C6CF69746F}
+ {F8D43559-8792-498B-AB51-211CA04CB4DF} = {A0F7DF3D-4B23-4243-9834-E35FBC15C9A8}
+ {7D8D2FEB-C2E5-4D54-8369-21DE2D44984A} = {A0F7DF3D-4B23-4243-9834-E35FBC15C9A8}
+ {1F25C4FB-D5EA-46BB-AB2B-AC5582E1AA9E} = {A0F7DF3D-4B23-4243-9834-E35FBC15C9A8}
+ {502D416A-D97E-46F6-B47F-85AB0BFDCD3A} = {C8607D23-999C-46EE-946A-85C6CF69746F}
+ {DB22ADE0-E49E-4B7E-9329-5AEA5F82072C} = {0D8B3E81-E824-4CE0-A516-87C4ECB59F52}
+ {B49CABB5-36C5-4028-BA42-0F3E0B94E33F} = {0D8B3E81-E824-4CE0-A516-87C4ECB59F52}
+ {1FF64B1A-907E-4056-82A5-67B3EFD45C78} = {0D8B3E81-E824-4CE0-A516-87C4ECB59F52}
+ {EA7D831A-03D1-4A08-805C-3E450EA024BC} = {C8607D23-999C-46EE-946A-85C6CF69746F}
+ {42D9D95B-3F19-46E3-9CCB-B9276A465E13} = {C8607D23-999C-46EE-946A-85C6CF69746F}
+ {F686EDF5-2B9C-4DE1-B197-785B38BE4B97} = {80ACDAD5-3FE5-4559-B11F-5F7CF18FF85C}
+ {91D4A03B-CCE7-4A9A-AA80-626251967A2B} = {80ACDAD5-3FE5-4559-B11F-5F7CF18FF85C}
+ {265016F3-AE52-4167-926A-52924366E7DD} = {80ACDAD5-3FE5-4559-B11F-5F7CF18FF85C}
+ {5C0936A5-3185-44C5-9B6B-FEB039CFB6F7} = {EA8DA886-D082-4565-95FA-7E70248260B7}
+ {6B0EA748-FC9A-467B-B3D4-A2A025EEBB29} = {EA8DA886-D082-4565-95FA-7E70248260B7}
+ EndGlobalSection
+EndGlobal