USE [dyzgclw]
GO
/** Object:  StoredProcedure [dbo].[Sp_GetLoanPlan]    Script Date: 10/23/2021 14:29:58 **/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/
生成贷款计划 qzf 2018-2-8 11:41:25
—表变量结果
declare @msg varchar(50)
exec Sp_GetLoanPlan ‘D001’,’2018-01-26’,’等额本息’,70000,3.5,6,20,0,@msg out
print @msg
—临时表结果
if(object_id(‘tempdb..#LoanPlan’)>0) drop table #LoanPlan
create table #LoanPlan (
        rid int,
        LoanNo VARCHAR(50) NOT NULL,
        LoanNoNum VARCHAR(50) NOT NULL DEFAULT ‘’,
        PayDate datetime,
        Debit numeric(24, 10) default 0 NOT NULL,
        Credit numeric(24, 10) default  0 NOT NULL,
        Principal numeric(24, 10) DEFAULT 0 NOT NULL,
        Rate numeric(24, 10) default 0 NOT NULL,
        Interest numeric(24, 10) default 0 NOT NULL,
        Balance numeric(24, 10) DEFAULT 0 NOT NULL,
        CurrentNum INT DEFAULT 0 NOT NULL
) 
declare @msg varchar(50)
insert into #LoanPlan exec  Sp_GetLoanPlan  ‘D001’,’2018-02-08’,’等额本息’,60000,3.5,6,12,0,@msg out
print @msg
select sum(principal),sum(round(principal,2)),sum(debit),sum(interest),sum(debit-interest) from #LoanPlan
/
ALTER procedure [dbo].Sp_GetLoanPlan, —贷款单号 
    @loandate    DATETIME,    —贷款日期
    @LoanWay    varchar(20), —等额本息,等额本金
    @LoanSum    decimal(20,2),  —贷款金额
    @Rate        numeric(24,10),    —利率
    @LoanMonths    INT,   —期数
    @payday        int,   —还款日
    @firstMonthPay  int,   —0:下月还款 1:当月还款,已过当月还款日,推到下月
    @msg  VARCHAR(200) out
)
AS
    declare @ExistTranCount INT
    DECLARE @LoanPlan TABLE(
        rid numeric IDENTITY(1,1) ,
        loanno VARCHAR(50) NOT NULL,
        loannonum VARCHAR(50) NOT NULL DEFAULT ‘’,
        paydate datetime,
        debit numeric(24, 10) default 0 NOT NULL,
        credit numeric(24, 10) default  0 NOT NULL,
        principal numeric(24, 10) DEFAULT 0 NOT NULL,
        rate numeric(24, 10) default 0 NOT NULL,
        interest numeric(24, 10) default 0 NOT NULL,
        balance numeric(24, 10) DEFAULT 0 NOT NULL,
        currentnum INT DEFAULT 0 NOT NULL
    ) 
    ——贷款计划
    declare @MonthsRate    numeric(24,10)    —月利率
    declare @Debit        decimal(20,3)    —应还
    declare @Principal    decimal(20,3)    —本金
    declare @Interest    decimal(20,3)   —利息
    declare @Balance    decimal(20,3)    —剩余金额
    declare @DebitL      decimal(20,3)    —保留两位小数
    declare @DebitYu      decimal(20,3)    —保留两位小数
    —-贷款
    declare @LoanInterset    numeric(24,10)  — 利息总和
    declare @q            numeric(24,10)   —利率 + 1
    declare @xishu        numeric(24,10)  —用于计算第一次等额本息
    declare @i            int               — 计次数
    declare @hk_rq        datetime
    declare    @yihuanbenjin decimal(20,3)  —已还本金
begin
    SET NOCOUNT ON
    SET XACT_ABORT ON
    if(isnull(@loanno,’’) = ‘’)
    BEGIN
        SET @msg = ‘贷款单号不能为空’
        GOTO errCheck
    END
    if(isnull(@loandate,’’) = ‘’)
    BEGIN
        SET @msg = ‘贷款日期不能为空’
        GOTO errCheck
    END
    if(isnull(@LoanWay,’’) = ‘’)
    BEGIN
        SET @msg = ‘贷款方式不能为空’
        GOTO errCheck
    END
    if(isnull(@LoanSum,0) = 0)
    BEGIN
        SET @msg = ‘贷款金额不能为0’
        GOTO errCheck
    END 
    if(isnull(@Rate,0) = 0)
    BEGIN
        SET @msg = ‘贷款利率不能为0’
        GOTO errCheck
    END 
    if(isnull(@LoanMonths,0) = 0)
    BEGIN
        SET @msg = ‘贷款月数不能为0’
        GOTO errCheck
    END 
    if(isnull(@payday,0) = 0)
    BEGIN
        SET @msg = ‘还款日不能为0’
        GOTO errCheck
    END
    select @ExistTranCount = @@trancount
    if @ExistTranCount > 0
        save transaction Tran_GetLoanPlan
    else 
    BEGIN
        begin transaction Tran_GetLoanPlan
    end
    set @rate = @rate / 100
    set @Rate=round(@Rate1000/120.001,10,1) —liuliang2011-05-09利率为年利率,这里换算为月利率
    select @hk_rq = cast( cast(DATEPART(year,@loandate) as varchar(4))+’-‘+cast(DATEPART(month,@loandate) as varchar(2))+’-‘+cast(@payday as varchar(2)) as datetime)
    IF(@firstMonthPay = 0 OR
       @firstMonthPay = 1 and @hk_rq < @loandate)
    BEGIN
        set @hk_rq = dateadd(month,1,@hk_rq)
    END
    if (@LoanWay = ‘等额本息’)
    begin
        select  @q  =  (1+convert(numeric(24,10), @Rate))     — 月利率 +1
        select  @MonthsRate = round(@Rate,10,1)   —月利率
        select  @xishu =round((@MonthsRate/(round(power((1+@MonthsRate),@LoanMonths),10,1) - 1)),10,1)   —-   系数 power(X,Y)函数是计算X的Y次幂的!例如:power(2,5)= 32   @fk_nx  期数
        —-  @xishu  用于计算第一个月应该还多少本金
        set @i=1 
       / 
        ==================定额还款公式==========================
        第一期本金 = 贷款额×利率/[(1+利率)×(1+利率)..n.- 1 ]
        第一期利息 = 贷款额×利率
        以后各期本金 = 上期本金×(1+利率)
        以后各期利息 = 剩余本金×利率
        剩余本金的第一期金额 = 贷款额
        剩余本金以后各期金额 = 贷款额 - 已还本金累计和(方法1)
        剩余本金以后各期金额 = 上期剩余本金金额 -上期本金金额(方法2)
        (注意:小数都上截断)
        /
        if @i <= @LoanMonths
        begin
            select @Principal = @LoanSum  @xishu  — 贷款金额  系数  ==  第一次的本金
            select @Interest = @LoanSum  @MonthsRate   —贷款金额  月利率  ==  贷款利息
            select @Debit = @Principal + @Interest   — 本金 + 贷款利息  == mqfkje  应还
            select @Balance = @LoanSum
            select @Balance = @Balance - @Principal   — 剩余本金
            ——取两位小数
            select @DebitL = @Debit  1000
            select @DebitYu = @DebitL % 10
            if (@DebitYu > 0)
            BEGIN
                select @DebitL = (@DebitL - @DebitL % 10 + 10  1.0)/1000
            end
            else
            begin
                select @DebitL = @DebitL  1.0 / 1000
            end
            ——————————
            ——插入贷款计划
            insert into @LoanPlan(LoanNo,LoanNoNum, PayDate,    Debit,  Principal,  Rate,        Interest,  Balance,currentnum)
                            values(@loanno,@loanno +’-‘+ convert(VARCHAR,@i),  @hk_rq,    @DebitL, @Principal, @MonthsRate, @Interest, @Balance,@i)
            if @@error > 0 goto errInsert
            set @i = @i + 1
            set @hk_rq=dateadd(mm,1,@hk_rq)——日期增加一个月
            —第二月的本金和
            if @i <= (@LoanMonths - 1)
            begin
                select @Principal = @Principal  @q
                select @Interest = @Balance  @MonthsRate
                select @Debit = @Principal + @Interest 
                select @Balance = @Balance - @Principal  — 剩余本金
                ——取两位小数
                select @DebitL = @Debit  1000
                select @DebitYu = @DebitL % 10
                if (@DebitYu > 0)
                begin
                    select @DebitL = (@DebitL - @DebitL % 10 + 10  1.0)/1000
                end
                else
                begin
                    select @DebitL = @DebitL  1.0 / 1000
                end
                ——————————
                ——插入贷款计划
                insert into @LoanPlan(LoanNo, LoanNoNum, PayDate,    Debit,  Principal,  Rate,        Interest,  Balance,currentnum)
                                values(@loanno, @loanno +’-‘+ convert(VARCHAR,@i), @hk_rq,  @DebitL, @Principal, @MonthsRate, @Interest, @Balance,@i)
                if @@error > 0 goto errInsert
                set @i = @i + 1
                set @hk_rq=dateadd(mm,1,@hk_rq)——日期增加一个月
                while @i<=(@LoanMonths-1)  — @i = 3
                begin 
                    /
                    select @Principal = @Principal  @q
                    select @Interest = @Balance  @MonthsRate
                    select @Debit = @Principal + @Interest 
                    select @Balance = @Balance - @Principal
                    /
                   —-博士的方式
                    select @Interest = @Balance  @MonthsRate
                    select @Principal = @Debit - @Interest
                    select @Balance = @Balance - @Principal 
                    ——取两位小数
                    select @DebitL = @Debit  1000
                    select @DebitYu = @DebitL % 10
                    if (@DebitYu > 0)
                    begin
                        select @DebitL = (@DebitL - @DebitL % 10 + 10  1.0)/1000
                    end
                    else
                    begin
                        select @DebitL = @DebitL  1.0 / 1000
                    end
                    ——————————
                    ——插入贷款计划
                    insert into @LoanPlan(LoanNo,LoanNoNum, PayDate,     Debit,  Principal,  Rate,        Interest,  Balance,currentnum)
                                    values(@loanno,@loanno +’-‘+ convert(VARCHAR,@i),  @hk_rq,    @DebitL, @Principal, @MonthsRate, @Interest, @Balance,@i)
                    if @@error > 0 goto errInsert
                    set @hk_rq=dateadd(mm,1,@hk_rq)
                    set @i=@i+1
                end
            end
            —最后一月
            if @i = @LoanMonths
            begin
                select @yihuanbenjin = sum(principal) from @LoanPlan where LoanNo = @loanno
                select @Principal = @LoanSum - @yihuanbenjin
                select @Interest = @Principal  @MonthsRate
                select @Debit = @Principal + @Interest 
                select @Balance = @Balance - @Principal
                ——取两位小数
                select @DebitL = @Debit  1000
                select @DebitYu = @DebitL % 10
                if (@DebitYu > 0)
                begin
                    select @DebitL = (@DebitL - @DebitL % 10 + 10  1.0)/1000
                end
                else
                begin
                    select @DebitL = @DebitL  1.0 / 1000
                end
                ——————————
                ——插入贷款计划
                insert into @LoanPlan(LoanNo,LoanNoNum, PayDate,     Debit,  Principal,  Rate,        Interest,  Balance,currentnum)
                                values(@loanno, @loanno +’-‘+ convert(VARCHAR,@i), @hk_rq,   @DebitL, @Principal, @MonthsRate, @Interest, @Balance,@i)
                if @@error > 0 goto errInsert
            end
        end
    end
    else if (@LoanWay = ‘等额本金’)
    begin
        set @Principal = @LoanSum/@LoanMonths
        set @i=1 
        select @Balance = @LoanSum
        while @i<=(@LoanMonths-1)
        begin
            set @Balance=@Balance-@Principal
            set @Debit = @Principal + @LoanSum  @Rate
            ——取两位小数
            select @DebitL = @Debit  1000
            select @DebitYu = @DebitL % 10
            if (@DebitYu > 0)
            begin
                select @DebitL = (@DebitL - @DebitL % 10 + 10  1.0)/1000
            end
            else
            begin
                select @DebitL = @DebitL  1.0 / 1000
            end
            ——————————
            ——插入贷款计划
            insert into @LoanPlan(LoanNo, PayDate,     Debit,                        Principal,  Rate,  Interest,  Balance,currentnum)
                             values(@loanno, @hk_rq,    @DebitL, @Principal, @Rate, @LoanSum  @Rate, @Balance,@i)
            if @@error > 0 goto errInsert
            —qzf 去掉set @LoanSum=@LoanSum-@Principal
            set @hk_rq=dateadd(mm,1,@hk_rq)
            set @i=@i+1
        end
        ——最后一个月
        set @Balance=@Balance-@Principal
        set @Debit = @Principal + @LoanSum  @Rate
        ——取两位小数
        select @DebitL = @Debit  1000
        select @DebitYu = @DebitL % 10
        if (@DebitYu > 0)
        begin
            select @DebitL = (@DebitL - @DebitL % 10 + 10  1.0)/1000
        end
        else
        begin
            select @DebitL = @DebitL  1.0 / 1000
        end
        ——————————
        if @i=@LoanMonths
        begin
            insert into @LoanPlan(LoanNo, PayDate,       Debit,                        Principal,  Rate,  Interest,        Balance,currentnum)
                            values(@loanno,  @hk_rq,    @DebitL  , @Principal, @Rate, @LoanSum  @Rate, @Balance,@i)
                            if @@error > 0 goto errInsert
            if @@error > 0 goto errInsert
        end
    end
    —qzf 2018-2-9 11:18:59 本金,利息更新为 2位小数
    DECLARE @diff NUMERIC(24,2)
    UPDATE @LoanPlan SET Principal = ROUND(Principal,2)
    UPDATE @LoanPlan SET Interest = debit - principal
    SET @diff = @LoanSum - (SELECT SUM(Principal) FROM @LoanPlan)
    PRINT @diff
    if(@diff <> 0)
    BEGIN
        UPDATE @LoanPlan SET Principal = Principal + @diff,Interest = Interest - @diff WHERE CurrentNum = @LoanMonths
    END 
    SELECT * FROM  @LoanPlan
       if @ExistTranCount = 0
    BEGIN
      commit tran Tran_GetLoanPlan
    end
    return 0
END
errCheck:
begin
    return(2001)
end
errUpdate:
begin
    ROLLBACK TRAN Tran_GetLoanPlan
    set @Msg = ‘更新出错’
    return(1001)
end
errInsert:
begin
    ROLLBACK TRAN Tran_GetLoanPlan
    set @Msg = ‘插入出错’
    return(1002)
end
errDelete:
begin
    ROLLBACK TRAN Tran_GetLoanPlan
    set @Msg = ‘删除出错’
    return(1003)
end
errNewList:
begin
    ROLLBACK TRAN Tran_GetLoanPlan
    set @Msg = ‘新建单号出错’
    return(1004)
end
//调用过程——————————————————————
 —获取还款计划
    create table #LoanPlan (
            rid int,
            LoanNo VARCHAR(50) NOT NULL,
            LoanNoNum VARCHAR(50) NOT NULL DEFAULT ‘’,
            PayDate datetime,
            Debit numeric(24, 10) default 0 NOT NULL,
            Credit numeric(24, 10) default  0 NOT NULL,
            Principal numeric(24, 10) DEFAULT 0 NOT NULL,
            Rate numeric(24, 10) default 0 NOT NULL,
            Interest numeric(24, 10) default 0 NOT NULL,
            Balance numeric(24, 10) DEFAULT 0 NOT NULL,
            CurrentNum INT DEFAULT 0 NOT NULL
    ) 
    insert into #LoanPlan exec  Sp_GetLoanPlan  @loanno,@loandate,@LoanWay,@LoanSum,@Rate,@LoanMonths,@payday,1,@msg out
    IF(@@error <> 0 OR @msg <> ‘’) GOTO errProc
