Merge pull request !1155 from dev_ljm_20241129
This commit is contained in:
ljm
2025-01-06 10:56:43 +00:00
committed by Gitee
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import pandas as pd
import calendar
from dateutil.relativedelta import relativedelta
from datetime import datetime, timedelta
@@ -186,77 +187,77 @@ class PropertyLeaseContract(models.Model):
# start_time = end_of_range
# return time_ranges
def my_compute_all_period_rent(self, start_date, end_date):
first_years_begin = self.first_years_begin if self.first_years_begin else 0
increments_every_few_years = self.increments_every_few_years
monthly_amount = self.total_area * self.unit_price # 月租金
unit_price = self.unit_price # 单价
rent_free_period_month = 0
# 先计算免租期
# if self.rent_free_period_year:
# rent_free_period_month += self.rent_free_period_year * 12
if self.rent_free_period_month:
rent_free_period_month += self.rent_free_period_month
free_start = start_date # 免租期开始
if rent_free_period_month:
free_start = start_date + relativedelta(months=rent_free_period_month)
all_period_rent = 0
if not increments_every_few_years:
# 计算剩余日期
delta = relativedelta(end_date, free_start)
months = delta.years * 12 + delta.months
all_period_rent += monthly_amount * months
else:
# 不递增年份的计算
increments_start = free_start # 平稳和递增开始
all_months = 0 # 第几月份
# 有免递增年份的计算
if first_years_begin:
first_index = 0 # 第几递增周期年
divided_year_segments = self.divide_time_range_fixed(start_date, end_date, 12)
for segment_year in divided_year_segments:
first_index += 1
increments_start = segment_year[1]
if first_years_begin and first_index >= first_years_begin:
# 进入 递增时间 跳出平稳计费极端
break
delta = relativedelta(segment_year[1], segment_year[0])
months = delta.years * 12 + delta.months
for month in range(months):
all_months += 1
# 判断是否是免租期
if all_months > rent_free_period_month:
all_period_rent += monthly_amount
# 开始递增
divided_increments_segments = self.divide_time_range_fixed(increments_start, end_date, increments_every_few_years * 12)
index = 0 # 第几递增周期年
for increments_year in divided_increments_segments:
index += 1
"""
increment_percentage = fields.Float(string="递增百分比")
increment_price = fields.Float(string="递增单价")
increment_amount = fields.Float(string="递增金额")
"""
increments_month = 0
if self.increment_method == "increment_price" and self.increment_value:
unit_price = unit_price + self.increment_value
monthly_amount = self.total_area * unit_price
if self.increment_method == "percentage" and self.increment_value:
monthly_amount = monthly_amount * self.increment_value
if self.increment_method == "increment_amount" and self.increment_value:
monthly_amount = monthly_amount + self.increment_value
delta = relativedelta(increments_year[1], increments_year[0])
months = delta.years * 12 + delta.months
# 判断第几月份进入 付费租期
for month in range(months):
all_months += 1
# 判断是否是免租期
if all_months > rent_free_period_month:
increments_month += 1
if increments_month:
all_period_rent += monthly_amount * increments_month
return all_period_rent
# def my_compute_all_period_rent(self, start_date, end_date):
# first_years_begin = self.first_years_begin if self.first_years_begin else 0
# increments_every_few_years = self.increments_every_few_years
# monthly_amount = self.total_area * self.unit_price # 月租金
# unit_price = self.unit_price # 单价
# rent_free_period_month = 0
# # 先计算免租期
# # if self.rent_free_period_year:
# # rent_free_period_month += self.rent_free_period_year * 12
# if self.rent_free_period_month:
# rent_free_period_month += self.rent_free_period_month
# free_start = start_date # 免租期开始
# if rent_free_period_month:
# free_start = start_date + relativedelta(months=rent_free_period_month)
#
# all_period_rent = 0
# if not increments_every_few_years:
# # 计算剩余日期
# delta = relativedelta(end_date, free_start)
# months = delta.years * 12 + delta.months
# all_period_rent += monthly_amount * months
# else:
# # 不递增年份的计算
# increments_start = free_start # 平稳和递增开始
# all_months = 0 # 第几月份
# # 有免递增年份的计算
# if first_years_begin:
# first_index = 0 # 第几递增周期年
# divided_year_segments = self.divide_time_range_fixed(start_date, end_date, 12)
# for segment_year in divided_year_segments:
# first_index += 1
# increments_start = segment_year[1]
# if first_years_begin and first_index >= first_years_begin:
# # 进入 递增时间 跳出平稳计费极端
# break
# delta = relativedelta(segment_year[1], segment_year[0])
# months = delta.years * 12 + delta.months
# for month in range(months):
# all_months += 1
# # 判断是否是免租期
# if all_months > rent_free_period_month:
# all_period_rent += monthly_amount
# # 开始递增
# divided_increments_segments = self.divide_time_range_fixed(increments_start, end_date, increments_every_few_years * 12)
# index = 0 # 第几递增周期年
# for increments_year in divided_increments_segments:
# index += 1
# """
# increment_percentage = fields.Float(string="递增百分比")
# increment_price = fields.Float(string="递增单价")
# increment_amount = fields.Float(string="递增金额")
# """
# increments_month = 0
# if self.increment_method == "increment_price" and self.increment_value:
# unit_price = unit_price + self.increment_value
# monthly_amount = self.total_area * unit_price
# if self.increment_method == "percentage" and self.increment_value:
# monthly_amount = monthly_amount * self.increment_value
# if self.increment_method == "increment_amount" and self.increment_value:
# monthly_amount = monthly_amount + self.increment_value
# delta = relativedelta(increments_year[1], increments_year[0])
# months = delta.years * 12 + delta.months
# # 判断第几月份进入 付费租期
# for month in range(months):
# all_months += 1
# # 判断是否是免租期
# if all_months > rent_free_period_month:
# increments_month += 1
# if increments_month:
# all_period_rent += monthly_amount * increments_month
# return all_period_rent
def action_generate_rental_charges(self):
"""
@@ -272,7 +273,7 @@ class PropertyLeaseContract(models.Model):
start_date = record.term_start_time
end_date = record.term_end_time + relativedelta(days=1)
all_period_rent = record.my_compute_all_period_rent(start_date, end_date)
all_period_rent = record.do_generate_details_core(start_date, end_date)
self.sudo().env["property.rent.list"].create({
"contract_id": record.id,
@@ -316,31 +317,35 @@ class PropertyLeaseContract(models.Model):
# todo 还没有计算递增递减
# todo 还没有计算首月优惠
# todo 还没有计算开始和结束不足月份和季度的计算比例
record = self
if not record.term_start_time:
raise UserError(_("请填写租期开始时间!"))
if not record.term_end_time:
raise UserError(_("请填写租期结束时间!"))
self.write({'breakdown_ids': [(5, 0, 0)]})
# self.sudo().env["property.rent.breakdown.line"].search([("breakdown_id", "in", record.ids)]).unlink()
for record in self:
if not record.term_start_time:
raise UserError(_("请填写租期开始时间!"))
if not record.term_end_time:
raise UserError(_("请填写租期结束时间!"))
record.write({'breakdown_ids': [(5, 0, 0)]})
start_date = record.term_start_time
end_date = record.term_end_time + relativedelta(days=1)
record.do_generate_details_core(start_date, end_date)
start_date = record.term_start_time
end_date = record.term_end_time + relativedelta(days=1)
def do_generate_details_core(record, start_date, end_date):
"""
计算核心算法
:return:
"""
all_period_rent = 0
first_years_begin = record.first_years_begin if record.first_years_begin else 0
increments_every_few_years = record.increments_every_few_years
monthly_amount = record.total_area * record.unit_price # 月租金
unit_price = record.unit_price # 单价
rent_free_period_month = 0
# 先计算免租期
# if record.rent_free_period_year:
# rent_free_period_month += record.rent_free_period_year * 12
if record.rent_free_period_month:
rent_free_period_month += record.rent_free_period_month
free_start = start_date # 免租期开始
if rent_free_period_month:
free_start = start_date + relativedelta(months=rent_free_period_month)
self.sudo().write({'breakdown_ids': [(0, 0, {
record.sudo().write({'breakdown_ids': [(0, 0, {
"unit_price": unit_price,
"monthly_amount": monthly_amount,
"breakdown_id": record.id,
@@ -349,91 +354,97 @@ class PropertyLeaseContract(models.Model):
"month_number": rent_free_period_month,
"period_rent": 0,
})]})
# self.sudo().env["property.rent.breakdown.line"].create({
# "unit_price": unit_price,
# "monthly_amount": monthly_amount,
# "breakdown_id": record.id,
# "start_data": start_date,
# "end_data": free_start - relativedelta(days=1),
# "month_number": rent_free_period_month,
# "period_rent": 0,
# })
# 在计算递增平稳年份租期
increments_start = free_start # 递增开始
# 如果没有递增 那么计算全部
if not increments_every_few_years:
# 如果免租期有天那么默认增加一个月
if record.rent_free_period_days:
# 计算这个月的天数
current_days = calendar.monthrange(free_start.year, free_start.month)[1]
current_no_free = (current_days - record.rent_free_period_days) / current_days
# 计算 免租期天的比值
record.sudo().write({'breakdown_ids': [(0, 0, {
"unit_price": unit_price,
"monthly_amount": monthly_amount,
"breakdown_id": record.id,
"start_data": free_start,
"end_data": free_start + relativedelta(months=1) - relativedelta(days=1),
"month_number": 1,
"period_rent": monthly_amount * 1 * current_no_free,
})]})
all_period_rent += monthly_amount * 1 * current_no_free
# 免租期后退一个月
free_start = free_start + relativedelta(months=1)
# 计算 免租期天的比值
delta = relativedelta(end_date, free_start)
months = delta.years * 12 + delta.months
self.sudo().write({'breakdown_ids': [(0, 0, {
record.sudo().write({'breakdown_ids': [(0, 0, {
"unit_price": unit_price,
"monthly_amount": monthly_amount,
"breakdown_id": record.id,
"start_data": increments_start,
"start_data": free_start,
"end_data": end_date - relativedelta(days=1),
"month_number": months,
"period_rent": monthly_amount * months,
})]})
# self.sudo().env["property.rent.breakdown.line"].create({
# "unit_price": unit_price,
# "monthly_amount": monthly_amount,
# "breakdown_id": record.id,
# "start_data": increments_start,
# "end_data": end_date - relativedelta(days=1),
# "month_number": months,
# "period_rent": monthly_amount * months,
# })
all_period_rent += monthly_amount * months
# 如果有递增
else:
all_months = 0 # 第几月份
# 有免递增年份的计算
first_years_begin_end = start_date
# 免递增年份计算
if first_years_begin:
first_index = 0 # 第几递增周期年
first_period_rent = 0 # 总收费
first_months = 0
divided_year_segments = self.divide_time_range_fixed(start_date, end_date, 12)
for segment_year in divided_year_segments:
first_index += 1
increments_start = segment_year[1]
if first_years_begin and first_index >= first_years_begin:
# 进入 递增时间 跳出平稳计费极端
break
delta = relativedelta(segment_year[1], segment_year[0])
months = delta.years * 12 + delta.months
# 判断第几月份进入 付费租期
for month in range(months):
all_months += 1
# 判断是否是免租期
if all_months > rent_free_period_month:
first_period_rent += monthly_amount
first_months += 1
if first_period_rent:
self.sudo().write({'breakdown_ids': [(0, 0, {
# 免递增结束时间
first_years_begin_end = start_date + relativedelta(months=first_years_begin * 12)
# 免租期结束时间 free_start
# 计算免租期和免增期的差值, 如果免租期超过免增期那么不存在免增期
if first_years_begin_end > free_start:
# 如果免租期有天那么默认增加一个月
if record.rent_free_period_days:
# 计算这个月的天数
current_days = calendar.monthrange(free_start.year, free_start.month)[1]
current_no_free = (current_days - record.rent_free_period_days) / current_days
# 计算 免租期天的比值
record.sudo().write({'breakdown_ids': [(0, 0, {
"unit_price": unit_price,
"monthly_amount": monthly_amount,
"breakdown_id": record.id,
"start_data": free_start,
"end_data": free_start + relativedelta(months=1) - relativedelta(days=1),
"month_number": 1,
"period_rent": monthly_amount * 1 * current_no_free,
})]})
all_period_rent += monthly_amount * 1 * current_no_free
# 免租期后退一个月
free_start = free_start + relativedelta(months=1)
# 计算剩下的免增期
delta = relativedelta(first_years_begin_end, free_start)
first_months = delta.years * 12 + delta.months
record.sudo().write({'breakdown_ids': [(0, 0, {
"unit_price": unit_price,
"monthly_amount": monthly_amount,
"breakdown_id": record.id,
"start_data": increments_start - relativedelta(months=first_months),
"end_data": increments_start - relativedelta(days=1),
"start_data": free_start,
"end_data": first_years_begin_end,
"month_number": first_months,
"period_rent": first_period_rent,
"period_rent": first_months * monthly_amount,
})]})
# self.sudo().env["property.rent.breakdown.line"].create({
# "unit_price": unit_price,
# "monthly_amount": monthly_amount,
# "breakdown_id": record.id,
# "start_data": increments_start - relativedelta(months=first_months),
# "end_data": increments_start - relativedelta(days=1),
# "month_number": first_months,
# "period_rent": first_period_rent,
# })
# 开始递增
divided_increments_segments = self.divide_time_range_fixed(increments_start, end_date, increments_every_few_years*12)
index = 0 # 第几递增周期年
all_period_rent += first_months * monthly_amount
# 免增期结束开始递增
divided_increments_segments = record.divide_time_range_fixed(first_years_begin_end, end_date, increments_every_few_years*12)
year_index = 0 # 第几递增周期年
all_months = 0 # 递增的第几个月
# 如果免租期 超过 免增期 那么递增期也需要排除
if first_years_begin_end < free_start:
delta = relativedelta(first_years_begin_end, free_start)
free_first_months = delta.years * 12 + delta.months
# 如果免租期有天那么默认增加一个月
if record.rent_free_period_days:
free_first_months = free_first_months + 1
else:
free_first_months = 0
for increments_year in divided_increments_segments:
index += 1
year_index += 1
"""
increment_percentage = fields.Float(string="递增百分比")
increment_price = fields.Float(string="递增单价")
@@ -451,17 +462,38 @@ class PropertyLeaseContract(models.Model):
if record.increment_method == "increment_amount" and record.increment_value:
monthly_amount = monthly_amount + record.increment_value
unit_price = monthly_amount / record.total_area
delta = relativedelta(increments_year[1], increments_year[0])
months = delta.years * 12 + delta.months
month_index = 0
# 判断第几月份进入 付费租期
for month in range(months):
# 判断第几月份进入 付费租期
month_index += 1 # 当前第个月
# 判断第几月份进入 付费租期
all_months += 1
if all_months == free_first_months:
# 如果免租期有天那么默认增加一个月
if record.rent_free_period_days:
current_now = increments_year[0] + relativedelta(months=month_index)
# 计算这个月的天数
current_days = calendar.monthrange(current_now.year, current_now.month)[1]
current_no_free = (current_days - record.rent_free_period_days) / current_days
# 计算 免租期天的比值
record.sudo().write({'breakdown_ids': [(0, 0, {
"unit_price": unit_price,
"monthly_amount": monthly_amount,
"breakdown_id": record.id,
"start_data": current_now,
"end_data": current_now + relativedelta(months=1) - relativedelta(days=1),
"month_number": 1,
"period_rent": monthly_amount * 1 * current_no_free,
})]})
all_period_rent += monthly_amount * 1 * current_no_free
# 判断是否是免租期
if all_months > rent_free_period_month:
if all_months > free_first_months:
increments_month += 1
if increments_month:
self.sudo().write({'breakdown_ids': [(0, 0, {
record.sudo().write({'breakdown_ids': [(0, 0, {
"unit_price": unit_price,
"monthly_amount": monthly_amount,
"breakdown_id": record.id,
@@ -470,15 +502,8 @@ class PropertyLeaseContract(models.Model):
"month_number": increments_month,
"period_rent": monthly_amount * increments_month,
})]})
# self.sudo().env["property.rent.breakdown.line"].create({
# "unit_price": unit_price,
# "monthly_amount": monthly_amount,
# "breakdown_id": record.id,
# "start_data": increments_year[1] - relativedelta(months=increments_month),
# "end_data": increments_year[1] - relativedelta(days=1),
# "month_number": increments_month,
# "period_rent": monthly_amount * increments_month,
# })
all_period_rent += monthly_amount * increments_month
return all_period_rent
# @api.onchange("first_year_rent")
# def _onchange_first_year_rent(self):