Example #1
0
        public static void ProcessContractTermination(this CourseContractRevision item, UserProfile handler = null)
        {
            ThreadPool.QueueUserWorkItem(t =>
            {
                try
                {
                    using (var models = new ModelSource <UserProfile>())
                    {
                        item = models.GetTable <CourseContractRevision>()
                               .Where(r => r.RevisionID == item.RevisionID).First();
                        ///1.變更狀態
                        ///
                        item.SourceContract.Status        = (int)Naming.CourseContractStatus.已終止;
                        item.SourceContract.ValidTo       = DateTime.Now;
                        item.CourseContract.EffectiveDate = DateTime.Now;
                        foreach (var lesson in item.SourceContract.RegisterLessonContract)
                        {
                            lesson.RegisterLesson.Attended = (int)Naming.LessonStatus.課程結束;
                        }
                        ///2.回沖繳款餘額
                        ///
                        var original  = item.SourceContract;
                        var totalPaid = original.TotalPaidAmount();
                        if (totalPaid > 0)
                        {
                            int refund;
                            int?returnAmt;

                            if (original.ContractType == (int)CourseContractType.ContractTypeDefinition.CGA)
                            {
                                var lessons = original.CountableRegisterLesson();

                                returnAmt = totalPaid
                                            - lessons.Where(r => r.LessonPriceType.IsDietaryConsult)
                                            .Sum(r => r.LessonPriceType.ListPrice * r.LessonTime.Count)
                                            - lessons.Where(r => !r.LessonPriceType.IsDietaryConsult)
                                            .Sum(r => r.LessonPriceType.ListPrice * r.LessonTime.Count);

                                refund = totalPaid
                                         - (item.ProcessingFee ?? 0)
                                         - (lessons.Select(r => r.LessonPriceType)
                                            .Where(l => l.IsDietaryConsult).Sum(l => l.ListPrice * l.BundleCount) ?? 0)
                                         - (lessons.Where(r => !r.LessonPriceType.IsDietaryConsult)
                                            .Sum(r => item.CourseContract.CourseContractExtension.SettlementPrice * r.LessonTime.Count) ?? 0);
                            }
                            else
                            {
                                var remained   = original.RemainedLessonCount();
                                var calculated = original.Lessons - remained;
                                returnAmt      = totalPaid - calculated
                                                 * original.LessonPriceType.ListPrice
                                                 * original.CourseContractType.GroupingMemberCount
                                                 * original.CourseContractType.GroupingLessonDiscount.PercentageOfDiscount / 100;

                                refund = totalPaid
                                         - (item.ProcessingFee ?? 0)
                                         - (calculated
                                            * item.CourseContract.CourseContractExtension.SettlementPrice
                                            * original.CourseContractType.GroupingMemberCount
                                            * original.CourseContractType.GroupingLessonDiscount.PercentageOfDiscount / 100 ?? 0);
                            }

                            refund         = Math.Max(refund, 0);
                            var adjustment = returnAmt - refund;

                            var dummyInvoice        = models.GetTable <InvoiceItem>().Where(i => i.No == "--").FirstOrDefault();
                            Payment balancedPayment = null;
                            balancedPayment         = new Payment
                            {
                                Status             = (int)Naming.CourseContractStatus.已生效,
                                ContractPayment    = new ContractPayment {
                                },
                                PaymentTransaction = new PaymentTransaction
                                {
                                    BranchID = item.SourceContract.CourseContractExtension.BranchID
                                },
                                PaymentAudit     = new Models.DataEntity.PaymentAudit {
                                },
                                PayoffAmount     = -refund,
                                PayoffDate       = DateTime.Today,
                                Remark           = "終止退款",
                                HandlerID        = handler != null ? handler.UID : item.CourseContract.AgentID,
                                PaymentType      = "現金",
                                TransactionType  = (int)Naming.PaymentTransactionType.合約終止沖銷,
                                AdjustmentAmount = adjustment != 0 ? adjustment : (int?)null,
                            };
                            balancedPayment.ContractPayment.ContractID = item.OriginalContract.Value;
                            if (dummyInvoice != null)
                            {
                                balancedPayment.InvoiceID = dummyInvoice.InvoiceID;
                            }
                            models.GetTable <Payment>().InsertOnSubmit(balancedPayment);

                            if (models.GetTable <ContractTrustTrack>().Any(a => a.ContractID == item.OriginalContract))
                            {
                                models.GetTable <ContractTrustTrack>().InsertOnSubmit(new ContractTrustTrack
                                {
                                    ContractID   = item.OriginalContract.Value,
                                    EventDate    = balancedPayment.PayoffDate.Value,
                                    TrustType    = Naming.TrustType.S.ToString(),
                                    ReturnAmount = returnAmt,
                                });
                            }

                            if (refund > 0)
                            {
                                //Logger.Debug("RevisionID: " + item.RevisionID);
                                //Logger.Debug("balance: " + balance);
                                models.CreateAllowanceForContract(original, refund, handler);
                            }
                        }

                        models.SubmitChanges();
                        original.TerminateRegisterLesson(models);
                    }
                }
                catch (Exception ex)
                {
                    ApplicationLogging.LoggerFactory.CreateLogger(typeof(TaskExtensionMethods))
                    .LogError(ex, ex.Message);
                }
            });
        }