internal static bool Convertible(this ContactAccountModel contactAccountModel)
        {
            NullGuard.NotNull(contactAccountModel, nameof(contactAccountModel));

            return(contactAccountModel.Accounting != null &&
                   contactAccountModel.Accounting.Convertible() &&
                   contactAccountModel.BasicAccount != null &&
                   contactAccountModel.PaymentTerm != null);
        }
        internal static IContactAccount Resolve(this ContactAccountModel contactAccountModel, IDictionary <int, IContactAccount> contactAccountDictionary)
        {
            NullGuard.NotNull(contactAccountModel, nameof(contactAccountModel))
            .NotNull(contactAccountDictionary, nameof(contactAccountDictionary));

            return(contactAccountDictionary.TryGetValue(contactAccountModel.ContactAccountIdentifier, out IContactAccount contactAccount)
                ? contactAccount
                : null);
        }
        internal static void ExtractPostingLines(this ContactAccountModel contactAccountModel, IReadOnlyCollection <PostingLineModel> postingLineModelCollection)
        {
            NullGuard.NotNull(contactAccountModel, nameof(contactAccountModel))
            .NotNull(postingLineModelCollection, nameof(postingLineModelCollection));

            contactAccountModel.PostingLines = postingLineModelCollection
                                               .Where(postingLineModel => postingLineModel.ContactAccountIdentifier != null &&
                                                      postingLineModel.ContactAccountIdentifier.Value == contactAccountModel.ContactAccountIdentifier &&
                                                      postingLineModel.PostingDate >= contactAccountModel.GetFromDateForPostingLines() &&
                                                      postingLineModel.PostingDate < contactAccountModel.GetToDateForPostingLines(1))
                                               .ToList();
        }
        internal static IContactAccount ToDomain(this ContactAccountModel contactAccountModel, MapperCache mapperCache, IConverter accountingModelConverter)
        {
            NullGuard.NotNull(contactAccountModel, nameof(contactAccountModel))
            .NotNull(mapperCache, nameof(mapperCache))
            .NotNull(accountingModelConverter, nameof(accountingModelConverter));

            lock (mapperCache.SyncRoot)
            {
                IAccounting accounting = accountingModelConverter.Convert <AccountingModel, IAccounting>(contactAccountModel.Accounting);

                return(contactAccountModel.ToDomain(accounting, mapperCache, accountingModelConverter));
            }
        }
        internal static IContactAccount ToDomain(this ContactAccountModel contactAccountModel, IAccounting accounting, MapperCache mapperCache, IConverter accountingModelConverter)
        {
            NullGuard.NotNull(contactAccountModel, nameof(contactAccountModel))
            .NotNull(accounting, nameof(accounting))
            .NotNull(mapperCache, nameof(mapperCache))
            .NotNull(accountingModelConverter, nameof(accountingModelConverter));

            lock (mapperCache.SyncRoot)
            {
                IContactAccount contactAccount = contactAccountModel.Resolve(mapperCache.ContactAccountDictionary);
                if (contactAccount != null)
                {
                    return(contactAccount);
                }

                IPaymentTerm paymentTerm = accountingModelConverter.Convert <PaymentTermModel, IPaymentTerm>(contactAccountModel.PaymentTerm);

                contactAccount = new ContactAccount(accounting, contactAccountModel.AccountNumber, contactAccountModel.BasicAccount.AccountName, paymentTerm)
                {
                    Description    = contactAccountModel.BasicAccount.Description,
                    Note           = contactAccountModel.BasicAccount.Note,
                    MailAddress    = contactAccountModel.MailAddress,
                    PrimaryPhone   = contactAccountModel.PrimaryPhone,
                    SecondaryPhone = contactAccountModel.SecondaryPhone
                };
                contactAccountModel.CopyAuditInformationTo(contactAccount);
                contactAccount.SetDeletable(contactAccountModel.Deletable);

                mapperCache.ContactAccountDictionary.Add(contactAccountModel.ContactAccountIdentifier, contactAccount);

                accounting.ContactAccountCollection.Add(contactAccount);

                contactAccount.ContactInfoCollection.Populate(contactAccount, contactAccountModel.StatusDate, contactAccountModel.StatusDateForInfos);

                if (contactAccountModel.PostingLines != null)
                {
                    contactAccount.PostingLineCollection.Add(contactAccountModel.PostingLines
                                                             .Where(postingLineModel => postingLineModel.Convertible() &&
                                                                    postingLineModel.PostingDate >= contactAccountModel.GetFromDateForPostingLines() &&
                                                                    postingLineModel.PostingDate < contactAccountModel.GetToDateForPostingLines(1))
                                                             .Select(postingLineModel => postingLineModel.ToDomain(accounting, contactAccount, mapperCache, accountingModelConverter))
                                                             .Where(postingLine => contactAccount.PostingLineCollection.Contains(postingLine) == false)
                                                             .ToArray());
                }

                return(contactAccount);
            }
        }
        private static IContactAccount ResolveContactAccount(ContactAccountModel contactAccountModel, IAccounting accounting, MapperCache mapperCache, IConverter accountingModelConverter)
        {
            NullGuard.NotNull(accounting, nameof(accounting))
            .NotNull(mapperCache, nameof(mapperCache))
            .NotNull(accountingModelConverter, nameof(accountingModelConverter));

            if (contactAccountModel == null)
            {
                return(null);
            }

            IContactAccount contactAccount = contactAccountModel.Resolve(mapperCache.ContactAccountDictionary) ?? contactAccountModel.ToDomain(accounting, mapperCache, accountingModelConverter);

            if (accounting.ContactAccountCollection.Contains(contactAccount) == false)
            {
                accounting.ContactAccountCollection.Add(contactAccount);
            }

            return(contactAccount);
        }