Esempio n. 1
0
        private Dictionary <string, long> ProfitAllPeriods(Scheme scheme, ProfitDetail profitDetail,
                                                           Address profitVirtualAddress, Address beneficiary, bool isView = false, string targetSymbol = null)
        {
            var profitsMap       = new Dictionary <string, long>();
            var lastProfitPeriod = profitDetail.LastProfitPeriod;

            var symbols = targetSymbol == null?scheme.ReceivedTokenSymbols.ToList() : new List <string>
            {
                targetSymbol
            };

            foreach (var symbol in symbols)
            {
                var totalAmount = 0L;
                for (var period = profitDetail.LastProfitPeriod;
                     period <= (profitDetail.EndPeriod == long.MaxValue
                        ? Math.Min(scheme.CurrentPeriod - 1,
                                   profitDetail.LastProfitPeriod.Add(ProfitContractConstants
                                                                     .MaximumProfitReceivingPeriodCountOfOneTime))
                        : Math.Min(scheme.CurrentPeriod - 1, profitDetail.EndPeriod));
                     period++)
                {
                    var periodToPrint = period;
                    var detailToPrint = profitDetail;
                    var distributedPeriodProfitsVirtualAddress =
                        GetDistributedPeriodProfitsVirtualAddress(profitVirtualAddress, period);
                    var distributedProfitsInformation =
                        State.DistributedProfitsMap[distributedPeriodProfitsVirtualAddress];
                    if (distributedProfitsInformation == null || distributedProfitsInformation.TotalShares == 0 ||
                        !distributedProfitsInformation.AmountsMap.Any() ||
                        !distributedProfitsInformation.AmountsMap.ContainsKey(symbol))
                    {
                        continue;
                    }

                    var amount = SafeCalculateProfits(profitDetail.Shares,
                                                      distributedProfitsInformation.AmountsMap[symbol], distributedProfitsInformation.TotalShares);

                    if (!isView)
                    {
                        Context.LogDebug(() =>
                                         $"{beneficiary} is profiting {amount} {symbol} tokens from {scheme.SchemeId.ToHex()} in period {periodToPrint}." +
                                         $"Sender's Shares: {detailToPrint.Shares}, total Shares: {distributedProfitsInformation.TotalShares}");
                        if (distributedProfitsInformation.IsReleased && amount > 0)
                        {
                            if (State.TokenContract.Value == null)
                            {
                                State.TokenContract.Value =
                                    Context.GetContractAddressByName(SmartContractConstants.TokenContractSystemName);
                            }
                            State.TokenContract.TransferFrom.Send(new TransferFromInput
                            {
                                From   = distributedPeriodProfitsVirtualAddress,
                                To     = beneficiary,
                                Symbol = symbol,
                                Amount = amount
                            });
                        }

                        lastProfitPeriod = period + 1;
                    }

                    totalAmount = totalAmount.Add(amount);
                }

                profitsMap.Add(symbol, totalAmount);
            }

            profitDetail.LastProfitPeriod = lastProfitPeriod;

            return(profitsMap);
        }
Esempio n. 2
0
        public async Task <bool> UpdateProfit(DateTime fromDate, DateTime toDate, string filter, string branchIds, Guid userId)
        {
            try
            {
                ///Nếu như !=0 tức là trên 1 tháng!
                var months = (toDate.Year * 12 + toDate.Month) - (fromDate.Year * 12 + fromDate.Month);
                if (months < 0)
                {
                    throw new Exception("Should be ToDate than FromDate");
                }
                else
                {
                    ///Tính thời gian về cuối tháng
                    DateTime ToDate_LastMonth = toDate;
                    DateTime ToDate_ThisMonth = toDate;

                    //loop
                    for (var i = 0; i <= months; i++)
                    {
                        //nếu như khác giá trị ban đầu thì fromDate tăng lên 1 tháng
                        if (i != 0)
                        {
                            fromDate         = fromDate.AddMonths(1);
                            ToDate_ThisMonth = new DateTime(fromDate.Year, fromDate.Month, 1);
                            toDate           = ToDate_ThisMonth.AddMonths(1).AddSeconds(-1);//ve cuoi thang nay
                        }
                        else
                        {
                            //Khi trường hợp nó bằng 0 tức là đang ở khoảng fromDate, cần phải đưa nó về cuối tháng
                            //vụ đưa về cuối tháng mỗi thèng tự xử rùi không cần quan tâm làm gì?
                            toDate = fromDate;
                        }

                        toDate = toDate.AddMonths(1).AddSeconds(-1);//ve cuoi thang nay
                        var results = this.GetProfitList(fromDate, toDate, filter, branchIds, 0, 0);
                        if (results != null && results.Count() > 0)
                        {
                            var endDate = fromDate.AddMonths(1);
                            var month   = endDate.Month;
                            var year    = endDate.Year;

                            //get Profit
                            var inv = this.appContext.Profit.FirstOrDefault(
                                p => p.CreatedDate.Month == month &&
                                p.CreatedDate.Year == year &&
                                p.IsDeleted == false);
                            //Initially ID
                            Guid ProfitId = Guid.NewGuid();
                            if (inv != null)
                            {
                                ProfitId = inv.ProfitId;
                            }
                            else
                            {
                                inv = new Profit
                                {
                                    ProfitId    = ProfitId,
                                    CreatedBy   = userId,
                                    CreatedDate = endDate,
                                    IsDeleted   = false,
                                    Note        = endDate.ToString(),
                                    UpdatedBy   = userId,
                                    UpdatedDate = DateTime.Now
                                };
                                await this.appContext.AddAsync(inv);
                            }

                            var invds = this.appContext.ProfitDetail.Where(p => p.ProfitId == inv.ProfitId);
                            foreach (var item in results)
                            {
                                var itemExist = invds.FirstOrDefault(p => p.BranchId == item.BranchId);
                                if (itemExist != null)
                                {
                                    itemExist.TotalPrice  = item.TotalPriceEnd;
                                    itemExist.UpdatedBy   = userId;
                                    itemExist.UpdatedDate = DateTime.Now;
                                }
                                else
                                {
                                    itemExist = new ProfitDetail
                                    {
                                        ProfitDetailId = Guid.NewGuid(),
                                        ProfitId       = ProfitId,
                                        TotalPrice     = item.TotalPriceEnd,
                                        CreatedBy      = userId,
                                        CreatedDate    = DateTime.Now,
                                        BranchId       = item.BranchId,
                                        IsDeleted      = false,
                                        UpdatedBy      = userId,
                                        UpdatedDate    = DateTime.Now
                                    };
                                    await this.appContext.AddAsync(itemExist);
                                }
                            }
                            await this.appContext.SaveChangesAsync();
                        }
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Esempio n. 3
0
        public override Empty AddBeneficiary(AddBeneficiaryInput input)
        {
            AssertValidInput(input);
            if (input.EndPeriod == 0)
            {
                // Which means this profit Beneficiary will never expired unless removed.
                input.EndPeriod = long.MaxValue;
            }

            var schemeId = input.SchemeId;
            var scheme   = State.SchemeInfos[schemeId];

            Assert(scheme != null, "Scheme not found.");

            // ReSharper disable once PossibleNullReferenceException
            Assert(
                Context.Sender == scheme.Manager || Context.Sender ==
                Context.GetContractAddressByName(SmartContractConstants.TokenHolderContractSystemName),
                "Only manager can add beneficiary.");

            Context.LogDebug(() =>
                             $"{input.SchemeId}.\n End Period: {input.EndPeriod}, Current Period: {scheme.CurrentPeriod}");

            Assert(input.EndPeriod >= scheme.CurrentPeriod,
                   $"Invalid end period. End Period: {input.EndPeriod}, Current Period: {scheme.CurrentPeriod}");

            scheme.TotalShares = scheme.TotalShares.Add(input.BeneficiaryShare.Shares);

            State.SchemeInfos[schemeId] = scheme;

            var profitDetail = new ProfitDetail
            {
                StartPeriod = scheme.CurrentPeriod.Add(scheme.DelayDistributePeriodCount),
                EndPeriod   = input.EndPeriod,
                Shares      = input.BeneficiaryShare.Shares,
            };

            var currentProfitDetails = State.ProfitDetailsMap[schemeId][input.BeneficiaryShare.Beneficiary];

            if (currentProfitDetails == null)
            {
                currentProfitDetails = new ProfitDetails
                {
                    Details = { profitDetail }
                };
            }
            else
            {
                currentProfitDetails.Details.Add(profitDetail);
            }

            // Remove details too old.
            var oldProfitDetails = currentProfitDetails.Details.Where(
                d => d.EndPeriod != long.MaxValue && d.LastProfitPeriod >= d.EndPeriod &&
                d.EndPeriod.Add(scheme.ProfitReceivingDuePeriodCount) < scheme.CurrentPeriod).ToList();

            foreach (var detail in oldProfitDetails)
            {
                currentProfitDetails.Details.Remove(detail);
            }

            State.ProfitDetailsMap[schemeId][input.BeneficiaryShare.Beneficiary] = currentProfitDetails;

            Context.LogDebug(() =>
                             $"Added {input.BeneficiaryShare.Shares} weights to scheme {input.SchemeId.ToHex()}: {profitDetail}");

            return(new Empty());
        }
Esempio n. 4
0
        public override Empty AddWeight(AddWeightInput input)
        {
            Assert(input.ProfitId != null, "Invalid profit id.");
            Assert(input.Receiver != null, "Invalid receiver address.");
            Assert(input.Weight >= 0, "Invalid weight.");

            if (input.EndPeriod == 0)
            {
                // Which means this profit receiver will never expired.
                input.EndPeriod = long.MaxValue;
            }

            var profitId   = input.ProfitId;
            var profitItem = State.ProfitItemsMap[profitId];

            Assert(profitItem != null, "Profit item not found.");

            if (profitItem == null)
            {
                return(new Empty());
            }

            Assert(input.EndPeriod >= profitItem.CurrentPeriod, "Invalid end period.");

            profitItem.TotalWeight += input.Weight;

            State.ProfitItemsMap[profitId] = profitItem;

            var profitDetail = new ProfitDetail
            {
                StartPeriod = profitItem.CurrentPeriod,
                EndPeriod   = input.EndPeriod,
                Weight      = input.Weight,
            };
            var currentProfitDetails = State.ProfitDetailsMap[profitId][input.Receiver];

            if (currentProfitDetails == null)
            {
                // TODO: Reduce Resource token of Profit Contract from DApp Developer because this behaviour will add a new key.
                currentProfitDetails = new ProfitDetails
                {
                    Details = { profitDetail }
                };
            }
            else
            {
                currentProfitDetails.Details.Add(profitDetail);
            }

            // Remove details too old.
            foreach (var detail in currentProfitDetails.Details.Where(
                         d => d.EndPeriod != long.MaxValue && d.LastProfitPeriod >= d.EndPeriod &&
                         d.EndPeriod.Add(profitItem.ExpiredPeriodNumber) < profitItem.CurrentPeriod))
            {
                currentProfitDetails.Details.Remove(detail);
            }

            State.ProfitDetailsMap[profitId][input.Receiver] = currentProfitDetails;

            return(new Empty());
        }