diff --git a/yuthon_property_approval/models/property_lease_contract.py b/yuthon_property_approval/models/property_lease_contract.py index c3e1064a1..dad82d42d 100644 --- a/yuthon_property_approval/models/property_lease_contract.py +++ b/yuthon_property_approval/models/property_lease_contract.py @@ -355,74 +355,244 @@ class PropertyLeaseContract(models.Model): record.do_generate_details_core(start_date, end_date) def do_generate_details_core(self, start_date, end_date): - """ - 计算核心算法 - :return: - """ all_period_rent = 0 - 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 monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金 - # 月租金 unit_price = self.unit_price # 单价 - rent_free_period_month = 0 + + # 如果有免租期 月 时间进行到 start_date + free_start = start_date 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) + free_start = start_date + relativedelta(months=self.rent_free_period_month) + if free_start > end_date: + free_start = end_date self.sudo().write({'breakdown_ids': [(0, 0, { "unit_price": unit_price, "monthly_amount": monthly_amount, "breakdown_id": self.id, "start_data": start_date, "end_data": free_start - relativedelta(days=1), - "month_number": rent_free_period_month, + "month_number": self.rent_free_period_month, "period_rent": 0, })]}) - # 如果没有递增 那么计算全部 - if not increments_every_few_years: - # 如果免租期有天那么默认增加一个月 - if self.rent_free_period_days: - # 计算这个月的天数 - current_days = calendar.monthrange(free_start.year, free_start.month)[1] - current_no_free = (current_days - self.rent_free_period_days) / current_days - # 计算 免租期天的比值 - self.sudo().write({'breakdown_ids': [(0, 0, { - "unit_price": unit_price, - "monthly_amount": monthly_amount, - "breakdown_id": self.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 if monthly_amount * 1 * current_no_free > 0 else 0, - })]}) - new_free_day_amount = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0 - all_period_rent += new_free_day_amount - # 免租期后退一个月 - free_start = free_start + relativedelta(months=1) - # 计算 免租期天的比值 - delta = relativedelta(end_date, free_start) + free_day_start = free_start + + add_year_index = 0 # 第几年 + year_month_index = 0 # 第几个月 + + monthly_amount_start_dict = {} + monthly_amount_end_dict = {} + monthly_amount_dict = {} + monthly_amount_unit_price = {} + monthly_amount_period_rent = {} + # 说明存在免增期 单独计算 + if start_date < end_date: + one_years_list = self.divide_time_range_fixed(start_date, end_date, 12) + for one_year in one_years_list: + add_year_index += 1 + # 是否存在免增期 + first_years_begin = self.first_years_begin if self.first_years_begin else 0 + # 存在递增期 并且进入递增金额计算 + if self.increments_every_few_years > 0 and add_year_index >= first_years_begin: + if add_year_index % self.increments_every_few_years == 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 + monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金 + if self.increment_method == "percentage" and self.increment_value: + monthly_amount = monthly_amount * (1 + (self.increment_value / 100)) + monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金 + unit_price = monthly_amount / self.total_area + if self.increment_method == "increment_amount" and self.increment_value: + monthly_amount = monthly_amount + self.increment_value + monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金 + unit_price = monthly_amount / self.total_area + # 开始时间, 结束时间 + one_year_start = one_year[0] + one_year_end = one_year[1] + one_month_list = self.divide_time_range_fixed(one_year_start, one_year_end, 1) + for one_month in one_month_list: + period_rent = monthly_amount + # 所有月统计 + year_month_index += 1 + # 如果开始时间 是 免租期月的结束时间,那么进入免租期日 + if one_month[0] == free_start: + # 如果免租期有天那么默认增加一个月 + if self.rent_free_period_days: + # 免租日的截至日期 + free_day_start = one_month[1] + # 计算这个月的天数 + total_days = (one_month[1] - one_month[0]).days + current_no_free = (total_days - self.rent_free_period_days) / total_days + period_rent = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0 + # 计算 免租期天的比值 + self.sudo().write({'breakdown_ids': [(0, 0, { + "unit_price": unit_price, + "monthly_amount": monthly_amount, + "breakdown_id": self.id, + "start_data": one_month[0], + "end_data": one_month[1] - relativedelta(days=1), + "month_number": 1, + "period_rent": period_rent, + })]}) + all_period_rent += period_rent + + # 已经跳出 免租期了 开始计费 + if one_month[0] >= free_day_start: + current_days = calendar.monthrange(one_month[0].year, one_month[0].month)[1] + total_days = (one_month[1] - one_month[0]).days + # 说明不足月 + if current_days > total_days: + current_no_free = total_days / current_days + period_rent = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0 + + all_period_rent += period_rent + + monthly_amount_dict[str(int(monthly_amount))] = monthly_amount + + if str(int(monthly_amount)) in monthly_amount_start_dict: + old_start = monthly_amount_start_dict.get(str(int(monthly_amount))) + monthly_amount_start_dict[str(int(monthly_amount))] = min(old_start, one_month[0]) + else: + monthly_amount_start_dict[str(int(monthly_amount))] = one_month[0] + + if str(int(monthly_amount)) in monthly_amount_end_dict: + old_start = monthly_amount_end_dict.get(str(int(monthly_amount))) + monthly_amount_end_dict[str(int(monthly_amount))] = max(old_start, one_month[1]) + else: + monthly_amount_end_dict[str(int(monthly_amount))] = one_month[1] + + if str(int(monthly_amount)) in monthly_amount_unit_price: + monthly_amount_unit_price[str(int(monthly_amount))] = unit_price + else: + monthly_amount_unit_price[str(int(monthly_amount))] = unit_price + + if str(int(monthly_amount)) in monthly_amount_period_rent: + old_period_rent = monthly_amount_period_rent.get(str(int(monthly_amount))) + monthly_amount_period_rent[str(int(monthly_amount))] = old_period_rent + period_rent + else: + monthly_amount_period_rent[str(int(monthly_amount))] = period_rent + + + # 开始统计月份阶段金额 + for k, v in monthly_amount_dict.items(): + unit_price = monthly_amount_unit_price.get(k) + monthly_amount = monthly_amount_dict.get(k) + period_rent = monthly_amount_period_rent.get(k) + start_time = monthly_amount_start_dict.get(k) + end_time = monthly_amount_end_dict.get(k) + + delta = relativedelta(end_time, start_time) months = delta.years * 12 + delta.months + if delta.days: + months += 1 + + if end_time != end_date: + end_time = end_time - relativedelta(days=1) + self.sudo().write({'breakdown_ids': [(0, 0, { "unit_price": unit_price, "monthly_amount": monthly_amount, "breakdown_id": self.id, - "start_data": free_start, - "end_data": end_date - relativedelta(days=1), + "start_data": start_time, + "end_data": end_time, "month_number": months, - "period_rent": monthly_amount * months, + "period_rent": period_rent, })]}) - all_period_rent += monthly_amount * months + + + def do_generate_details_core_1(self, start_date, end_date): + """ + 计算核心算法 + :return: + """ + all_period_rent = 0 # 总金额 + monthly_amount = self.total_area * self.unit_price + monthly_amount = float_round(monthly_amount, precision_digits=0, rounding_method='HALF-UP') # 月租金 + # 月租金 + unit_price = self.unit_price # 单价 + + # 如果有免租期 月 时间进行到 start_date + free_start = start_date + if self.rent_free_period_month: + free_start = start_date + relativedelta(months=self.rent_free_period_month) + if free_start > end_date: + free_start = end_date + self.sudo().write({'breakdown_ids': [(0, 0, { + "unit_price": unit_price, + "monthly_amount": monthly_amount, + "breakdown_id": self.id, + "start_data": start_date, + "end_data": free_start - relativedelta(days=1), + "month_number": self.rent_free_period_month, + "period_rent": 0, + })]}) + + # 如果没有递增 那么计算全部 + if not self.increments_every_few_years: + # 如果免租期有天那么默认增加一个月 + # 如果有免增期 日 + free_start_day = free_start + if self.rent_free_period_days: + free_start_day = free_start + relativedelta(months=self.rent_free_period_days) + if free_start_day < end_date: + # 计算这个月的天数 + current_days = calendar.monthrange(free_start.year, free_start.month)[1] + current_no_free = (current_days - self.rent_free_period_days) / current_days + period_rent = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0 + # 计算 免租期天的比值 + self.sudo().write({'breakdown_ids': [(0, 0, { + "unit_price": unit_price, + "monthly_amount": monthly_amount, + "breakdown_id": self.id, + "start_data": free_start, + "end_data": free_start_day - relativedelta(days=1), + "month_number": 1, + "period_rent": period_rent, + })]}) + all_period_rent += period_rent + + # 计算 剩余日期的金额 + if free_start_day < end_date: + delta = relativedelta(end_date, free_start_day) + months = delta.years * 12 + delta.months + free_start_day_end = free_start_day + relativedelta(months=months) + self.sudo().write({'breakdown_ids': [(0, 0, { + "unit_price": unit_price, + "monthly_amount": monthly_amount, + "breakdown_id": self.id, + "start_data": free_start_day, + "end_data": free_start_day_end - relativedelta(days=1), + "month_number": months, + "period_rent": monthly_amount * months, + })]}) + all_period_rent += monthly_amount * months + # 说明最后还有几天 + if delta.days > 0: + current_days = calendar.monthrange(free_start_day_end.year, free_start_day_end.month)[1] + current_no_free = delta.days / current_days + period_rent = monthly_amount * 1 * current_no_free if monthly_amount * 1 * current_no_free > 0 else 0 + # 计算 免租期天的比值 + self.sudo().write({'breakdown_ids': [(0, 0, { + "unit_price": unit_price, + "monthly_amount": monthly_amount, + "breakdown_id": self.id, + "start_data": free_start_day_end, + "end_data": end_date, + "month_number": 1, + "period_rent": period_rent, + })]}) + # 如果有递增 else: first_years_begin_end = start_date # 免递增年份计算 - if first_years_begin > 1: + if self.first_years_begin > 1: # 免递增结束时间 - first_years_begin_end = start_date + relativedelta(months=(first_years_begin -1) * 12) + first_years_begin_end = start_date + relativedelta(months=(self.first_years_begin -1) * 12) # 免租期结束时间 free_start # 计算免租期和免增期的差值, 如果免租期超过免增期那么不存在免增期 if first_years_begin_end > free_start: diff --git a/yuthon_property_approval/views/property_lease_contract.xml b/yuthon_property_approval/views/property_lease_contract.xml index 7fd68ca39..141f3ab47 100644 --- a/yuthon_property_approval/views/property_lease_contract.xml +++ b/yuthon_property_approval/views/property_lease_contract.xml @@ -88,6 +88,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -205,10 +261,7 @@ - @@ -225,61 +278,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -296,7 +294,7 @@ - + @@ -374,6 +372,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -493,7 +547,6 @@ - @@ -515,6 +568,16 @@ + + + + + + + + + + @@ -528,6 +591,16 @@ + + + + + + + + + + @@ -558,15 +631,21 @@ - - - - - - - - - + + + + + + + + + + + + + + +