python 如何在每次迭代中增加日期

j8yoct9x  于 2023-09-29  发布在  Python
关注(0)|答案(2)|浏览(123)

我试图实现的是根据所选择的付款频率来预测付款日期。例如,当用户选择每月的支付频率时,系统应该能够预测12个月的支付日期,第一个支付日期应该是date_start,然后递增30以预测下一个支付日期。这是我代码。

def action_compute_amortization(self):
        """This automatically create the installment the employee need to pay to
        company based on payment start date and the no of installments.
            """
        for rec in self:
            rec.amortization_lines.unlink()
            date_start = rec.date_from
            days_in_a_year = rec.coverage_term
            payment_freq = rec.premium_frequency
            frequency : dict = {
                'monthly':round(days_in_a_year/30),
                'quarterly': round(days_in_a_year/90),
                'biannually': round(days_in_a_year/182),
                'yearly': round(days_in_a_year/days_in_a_year)
            }
            term = frequency.get(payment_freq,days_in_a_year)
            amount = rec.policy_risk_ids.cover_ids.premium_currency
            for i in range(1,days_in_a_year + 1):
                while term > 0:
                    payment_date = date_start
                    if payment_freq == "monthly":
                        payment_date = date_utils.add(date_start, days=30)
                    elif payment_freq == "quarterly":
                        payment_date = date_utils.add(date_start, days=90)
                    elif payment_freq == "biannually":
                        payment_date = date_utils.add(date_start, days=182)
                    elif payment_freq == "yearly":
                        payment_date = date_start
                    else:
                        payment_date = date_utils.add(date_start, hours=24)
                    self.env['epgi.policy.amortization'].create({
                        'payment_date': payment_date,
                        'amount': amount,
                        'insured_id': rec.insured_id.id,
                        'policy_id': rec.id})
                    term -= 1
        return True

但我没有得到理想的结果,因为我只得到立即下一个付款日期。但我需要的日期_开始是第一期付款日期,然后下一个付款日期,如果每月应增加旧日期30天,等等。
我会很感激所有的帮助。

lnvxswe2

lnvxswe21#

我对你代码中的参数含义有一些问题。
所以我实现了一个简单的示例展示给大家,希望能对大家有所帮助。
下面是我的代码,它将计算并记录365天内的所有payment_date,deadDays的值可以任意指定

import  datetime
import math
from decimal import *

if __name__ == '__main__':
    print(datetime.date.today())

    # the user input payment_freq , modify this
    payment_freq = "monthly"

    # the user input total amount , modify this
    totalAmount = Decimal.from_float(1000)

    payment_cycle = 0
    if payment_freq == "monthly":
        payment_cycle = 30
    elif payment_freq == "quarterly":
        payment_cycle = 90
    elif payment_freq == "biannually":
        payment_cycle = 182
    elif payment_freq == "yearly":
        payment_cycle = 365
    else:
        payment_cycle = 1

    deadDays = 365
    cycle = round(deadDays / payment_cycle)
    i = 0
    # transfer the payment_date from a dateTime to a list of dateTime
    payment_date  = []
    tempTime = datetime.date.today()

    for i in range (0 ,cycle):
        tempTime = tempTime +datetime.timedelta(days=30)
        payment_date .append(tempTime)
    divideAmount = math.ceil(totalAmount *100/Decimal.from_float(cycle))/100

    # the result , i print it ,you can use your function  deal with  those value
    print(payment_date)
    print(divideAmount)
gzszwxb4

gzszwxb42#

所以,如果将来有人遇到这个问题,这就是我解决它的方法。

def action_compute_amortization(self):
        """This automatically create the installment the employee need to pay to
        company based on payment start date and the no of installments.
            """
        ModelObj = self.env['epgi.policy.amortization'].sudo()
        for rec in self:
            rec.amortization_lines.unlink()
            date_start = datetime.datetime.strptime(str(rec.date_from), '%Y-%m-%d %H:%M:%S')
            date_end = datetime.datetime.strptime(str(rec.date_to), '%Y-%m-%d %H:%M:%S')
            #format date to string Year Month Day
            d_f = date_start.strftime("%Y%m%d") 
            d_t = date_end.strftime("%Y%m%d")
            #date accepts 3 args; Y,M,D. using index, I got the required values and formated them to int
            date1 = date(int(d_f[:4]),int(d_f[4:6]),int(d_f[6:])) 
            date2 = date(int(d_t[:4]),int(d_t[4:6]),int(d_t[6:]))
            # getting the number of days between start date and end date
            r = date2 - date1
            _logger.info(f'days {r.days}')
            payment_freq = self.premium_frequency
            account = self.env['account.move'].search([('policy_id','=',rec.id)])
            # getting the paid amount
            paid_amount = sum(account.filtered(lambda x: x.policy_transaction_type =="premium").\
                invoice_line_ids.mapped('price_subtotal'))
            reduce_by = 0
            if payment_freq == 'daily':
                no_repayments = r.days # to get the days btween start and end dates
                daily_payment = rec.actual_si_currency / no_repayments #to get the accurate amount to be paid daily
                payments = int(paid_amount // daily_payment)
                reduce_by = r.days - payments
                for i in range(payments):
                    ModelObj.create({
                        'payment_date': date_start,
                        'amount': daily_payment,
                        'insured_id': rec.insured_id.id,
                        'policy_id': rec.id,
                        'payment_status': 'Paid'
                    })
                    date_start = date_start + timedelta(days=1)
                for i in range(reduce_by):
                    ModelObj.create({
                        'payment_date': date_start,
                        'amount': daily_payment,
                        'insured_id': rec.insured_id.id,
                        'policy_id': rec.id
                    })
                    date_start = date_start + timedelta(days=1)
            elif payment_freq == 'monthly':
                no_repayments = r.days //30.25 
                # Calculate the monthly premium amount
                monthly_payment = rec.actual_si_currency / no_repayments
                payments = int(paid_amount // monthly_payment) #to get the amount of times payment was made
                reduce_by = int(r.days //30.25 - payments)
                for i in range(payments):
                    ModelObj.create({
                    'payment_date': date_start,
                    'amount': monthly_payment,
                    'insured_id': rec.insured_id.id,
                    'policy_id': rec.id,
                    'payment_status': 'Paid'
                    })
                    date_start = date_start + timedelta(days=30)
                # Generate payments for the next 12 months
                
                for i in range(reduce_by):
                    ModelObj.create({
                        'payment_date': date_start.strftime("%Y-%m-%d"),
                        'amount': monthly_payment,
                        'insured_id': rec.insured_id.id,
                        'policy_id': rec.id})
                    
                    # Move the payment_date to the next month
                    date_start += timedelta(days=30)
            elif payment_freq == 'quarterly':
                no_repayments = r.days // 91.25 # the number of days between start and end dates divid by 91.25 to get the number of times quarters to pay incase policy duration is more than a year
                quarterly_payment =  rec.actual_si_currency / no_repayments
                payments = int(paid_amount // quarterly_payment)
                reduce_by = int(r.days // 91.25 - payments)
                for i in range(payments):
                    ModelObj.create({
                    'payment_date': date_start,
                    'amount': quarterly_payment,
                    'insured_id': rec.insured_id.id,
                    'policy_id': rec.id,
                    'payment_status': 'Paid'
                    })
                    date_start = date_start + timedelta(days=365 / 4)

                for i in range(reduce_by):
                    ModelObj.create({
                        'payment_date': date_start,
                        'amount': quarterly_payment,
                        'insured_id': rec.insured_id.id,
                        'policy_id': rec.id})
                    date_start = date_start + timedelta(days=365 / 4)
            elif payment_freq == 'biannually':
                no_repayments = r.days // 182.5  # the number of days between start and end dates divid by 182.5  to get the number of times bianually to pay incase policy duration is more than a year
                biannual_payment = rec.actual_si_currency / no_repayments
                payments = int(paid_amount // biannual_payment)
                reduce_by = int(r.days // 182.5 - payments)
                for i in range(payments):
                    ModelObj.create({
                    'payment_date': date_start,
                    'amount': biannual_payment,
                    'insured_id': rec.insured_id.id,
                    'policy_id': rec.id,
                    'payment_status': 'Paid'
                    })
                    date_start = date_start + timedelta(days=365 / 2)
                for i in range(reduce_by):
                    ModelObj.create({
                        'payment_date': date_start,
                        'amount': biannual_payment,
                        'insured_id': rec.insured_id.id,
                        'policy_id': rec.id})
                    date_start = date_start + timedelta(days=365 / 2) 
            else: #Yearly payment
                total_years = r.days // 365
                yearly_payment = rec.actual_si_currency / total_years
                payments = int(paid_amount // yearly_payment)
                reduce_by = r.days // 365
                for i in range(payments):
                    ModelObj.create({
                    'payment_date': date_start,
                    'amount': yearly_payment,
                    'insured_id': rec.insured_id.id,
                    'policy_id': rec.id,
                    'payment_status': 'Paid'
                    })
                    date_start = date_start + timedelta(days=365)
                for i in range(reduce_by):
                    ModelObj.create({
                        'payment_date': date_start,
                        'amount': yearly_payment,
                        'insured_id': rec.insured_id.id,
                        'policy_id': rec.id})
                    date_start = date_start + timedelta(days=365)
        return True

相关问题