@@ -891,6 +891,8 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
and field_attrs.name.name == field_inst.attrib["name"]
|
||||
):
|
||||
flag_show = True
|
||||
if field_attrs.name.name in ["code", "name_title"]:
|
||||
readonly_arr.append(node.node_name)
|
||||
if field_attrs.readonly:
|
||||
readonly_arr.append(node.node_name)
|
||||
if field_attrs.required:
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
'wizard/property_tenant_wizard_views.xml',
|
||||
'wizard/evaluation_plan_wizard_views.xml',
|
||||
'wizard/property_water_wizard_views.xml',
|
||||
'wizard/receivable_log_wizard_views.xml',
|
||||
'wizard/property_statements_wizard_views.xml',
|
||||
'views/menuitem.xml',
|
||||
],
|
||||
|
||||
@@ -33,21 +33,86 @@ class PropertyAccountsReceivable(models.Model):
|
||||
is_billing = fields.Boolean(string='开票')
|
||||
is_reconciliation = fields.Boolean(string='对账')
|
||||
difference_amount = fields.Float(string='差额')
|
||||
delivered1 = fields.Float(string='已交')
|
||||
delivered = fields.Boolean()
|
||||
submitted = fields.Float(string='未交')
|
||||
is_invalid = fields.Boolean(string='作废')
|
||||
is_red = fields.Boolean(string='红冲')
|
||||
red_state_date = fields.Date(string='红冲时间')
|
||||
is_push = fields.Boolean(string='已推送')
|
||||
management_type_id = fields.Many2one('yuthon.management.type', string='应收类型')
|
||||
last_update_time = fields.Datetime(string='最后修改时间')
|
||||
receivable_log = fields.Text(string='应收日志')
|
||||
|
||||
def unlink(self):
|
||||
return super().unlink()
|
||||
@api.onchange('original_amount', 'delivered1')
|
||||
def _get_submitted(self):
|
||||
for record in self:
|
||||
record.submitted = record.original_amount - record.delivered1
|
||||
|
||||
def invalid(self):
|
||||
receivable_log = (f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name}的应收账单状态修改为作废')
|
||||
for record in self:
|
||||
original_log = record.receivable_log or ''
|
||||
if original_log:
|
||||
new_log = f"{original_log}\n{receivable_log}"
|
||||
else:
|
||||
new_log = receivable_log
|
||||
return self.write({'is_invalid': True,
|
||||
'receivable_log': new_log
|
||||
})
|
||||
|
||||
# 激活
|
||||
def suspend(self):
|
||||
return self.write({'is_suspend': False})
|
||||
|
||||
receivable_log = (
|
||||
f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name}的应收账单挂起')
|
||||
for record in self:
|
||||
original_log = record.receivable_log or ''
|
||||
if original_log:
|
||||
new_log = f"{original_log}\n{receivable_log}"
|
||||
else:
|
||||
new_log = receivable_log
|
||||
return self.write({'is_suspend': False,'receivable_log': new_log})
|
||||
|
||||
# 挂起
|
||||
def unsuspend(self):
|
||||
return self.write({'is_suspend': True})
|
||||
receivable_log = (
|
||||
f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name}的应收账单取消挂起')
|
||||
for record in self:
|
||||
original_log = record.receivable_log or ''
|
||||
if original_log:
|
||||
new_log = f"{original_log}\n{receivable_log}"
|
||||
else:
|
||||
new_log = receivable_log
|
||||
return self.write({'is_suspend': True,
|
||||
'receivable_log':new_log
|
||||
})
|
||||
|
||||
# 红冲
|
||||
def all_red(self):
|
||||
receivable_ids = self.env["property.accounts.receivable"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
property_list = []
|
||||
for receivable in receivable_ids:
|
||||
property_list.append(receivable.property_id.id)
|
||||
property_names = ",".join(property_list)
|
||||
receivable_log = (f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {property_names}的应收账单红冲')
|
||||
for record in self:
|
||||
original_log = record.receivable_log or ''
|
||||
if original_log:
|
||||
new_log = f"{original_log}\n{receivable_log}"
|
||||
else:
|
||||
new_log = receivable_log
|
||||
receivable.write({'is_red': True, 'red_state_date': fields.Date.today(), 'receivable_log': new_log})
|
||||
|
||||
|
||||
def receivable_log_wizard(self):
|
||||
return {
|
||||
'name': '应收日志',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'receivable.log.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_name' : self.receivable_log
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo import models, fields, api, exceptions, _
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@@ -20,7 +19,6 @@ class PropertyBankStatements(models.Model):
|
||||
message = fields.Char('回单个性化信息')
|
||||
number = fields.Char('凭证号')
|
||||
extract = fields.Char('摘要')
|
||||
is_put = fields.Boolean('是否推送')
|
||||
start_time = fields.Datetime('交易时间')
|
||||
contract_account = fields.Char(string="合同累计应收")
|
||||
contract_penalty = fields.Char(string="合同累计违约金")
|
||||
@@ -28,10 +26,27 @@ class PropertyBankStatements(models.Model):
|
||||
is_reconciliation = fields.Boolean('是否已对账')
|
||||
voucher_type = fields.Selection([('electronic_transfer', '电子转账凭证'), ('telegraphic_transfer', '电汇凭证')], string='凭证种类')
|
||||
remake = fields.Text('备注')
|
||||
registered = fields.Float('挂账')
|
||||
property_ids = fields.Many2many('yuthon.property', string='物业地址')
|
||||
bank_state = fields.Selection([('not_reconciled', '未对账'), ('reconciled', '已对账'), ('other', '其他')], string='状态', default='not_reconciled')
|
||||
|
||||
def unlink(self):
|
||||
return super().unlink()
|
||||
def other(self):
|
||||
for rec in self:
|
||||
rec.bank_state = 'other'
|
||||
receivable_ids = self.env['property.accounts.receivable'].search([('lessee_id.name', '=', self.name_account)])
|
||||
property_list = []
|
||||
for property in self.property_ids:
|
||||
property_list.append(property.name)
|
||||
property_names = ",".join(property_list)
|
||||
for receivable in receivable_ids:
|
||||
receivable_log = f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {property_names} 的银行对账单状态修改为其他'
|
||||
for record in self:
|
||||
original_log = record.receivable_log or ''
|
||||
if original_log:
|
||||
new_log = f"{original_log}\n{receivable_log}"
|
||||
else:
|
||||
new_log = receivable_log
|
||||
receivable.write({'receivable_log': new_log})
|
||||
|
||||
@api.onchange('name')
|
||||
def _onchange_name(self):
|
||||
@@ -51,8 +66,7 @@ class PropertyBankStatements(models.Model):
|
||||
self.property_ids = [(6, 0, property_ids)]
|
||||
self.contract_ids = [(6, 0, contract_ids.ids)] if contract_ids else []
|
||||
|
||||
@api.onchange('property_ids')
|
||||
def _onchange_property_or_contract_ids(self):
|
||||
def binding_information(self):
|
||||
bank_list = []
|
||||
if self.name:
|
||||
bank_id = self.env['property.bank.line'].search([('bank', '=', self.name)])
|
||||
@@ -63,6 +77,22 @@ class PropertyBankStatements(models.Model):
|
||||
lessee_id = lease_contract_id.lessee_id
|
||||
bank_list.append((0, 0, {'name': self.name_account, 'user': lessee_id.name, 'bank': self.name,}))
|
||||
lessee_id.bank_ids = bank_list
|
||||
|
||||
receivable_ids = self.env['property.accounts.receivable'].search([('lessee_id.name', '=', self.name_account)])
|
||||
property_list = []
|
||||
for property in self.property_ids:
|
||||
property_list.append(property.name)
|
||||
property_names = ",".join(property_list)
|
||||
for receivable in receivable_ids:
|
||||
receivable_log = f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {property_names} 的对账进行绑定新信息'
|
||||
for record in self:
|
||||
original_log = record.receivable_log or ''
|
||||
if original_log:
|
||||
new_log = f"{original_log}\n{receivable_log}"
|
||||
else:
|
||||
new_log = receivable_log
|
||||
receivable.write({'receivable_log': new_log})
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
record = super(PropertyBankStatements, self).create(vals)
|
||||
@@ -87,6 +117,29 @@ class PropertyBankStatements(models.Model):
|
||||
self.property_ids = [(6, 0, property_ids)]
|
||||
self.contract_ids = [(6, 0, contract_ids.ids)] if contract_ids else []
|
||||
|
||||
def put_button_cancel(self):
|
||||
for record in self:
|
||||
record.is_put = False
|
||||
|
||||
def handle_contract_penalty(self):
|
||||
'''
|
||||
处理合同违约金
|
||||
:param record: property.bank.statements 记录
|
||||
:return:
|
||||
'''
|
||||
record = self.env["property.bank.statements"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
for contract_id in record.contract_ids:
|
||||
receivable_id = self.env['property.accounts.receivable'].search([('contract_id', '=', contract_id.id)])
|
||||
if receivable_id:
|
||||
dt = datetime.strptime(str(record.start_time), '%Y-%m-%d %H:%M:%S').date() # 流水交易时间
|
||||
due = datetime.strptime(str(receivable_id.due_date), '%Y-%m-%d').date() + relativedelta(months=1, day=1) # 应收日期
|
||||
# 判断是否违约
|
||||
if receivable_id.submitted and not receivable_id.is_reconciliation or not receivable_id.is_suspend:
|
||||
original_amount = (due - dt).days * receivable_id.original_amount * float(receivable_id.contract_id.percentage_liquidated_damages.name)
|
||||
self.env['property.penalty.list'].create({
|
||||
'contract_id': contract_id.id,
|
||||
'property_id': contract_id.lease_ids[0].address_id.id,
|
||||
'lessee_id': contract_id.lessee_id.id,
|
||||
'original_amount': original_amount
|
||||
})
|
||||
receivable_id.write({'penalty':original_amount})
|
||||
receivable_id.is_reconciliation = True
|
||||
|
||||
|
||||
@@ -42,4 +42,7 @@ class PropertyRentList(models.Model):
|
||||
return super(PropertyRentList, self).write(vals)
|
||||
|
||||
def unlink(self):
|
||||
receivable_ids = self.env['property.accounts.receivable'].search([('lessee_id', '=', self.lessee_id.id)])
|
||||
for receivable in receivable_ids:
|
||||
receivable.write({'receivable_log': f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name} 的租金列表进行删除'})
|
||||
return super().unlink()
|
||||
|
||||
@@ -87,5 +87,6 @@ access_property_floor_setting,property_floor_setting,model_property_floor_settin
|
||||
access_property_evaluation_plan,property_evaluation_plan,model_property_evaluation_plan,base.group_user,1,1,1,1
|
||||
access_evaluation_company,evaluation_company,model_evaluation_company,base.group_user,1,1,1,1
|
||||
access_evaluation_plan_wizard,evaluation_plan_wizard,model_evaluation_plan_wizard,base.group_user,1,1,1,1
|
||||
access_receivable_log_wizard, receivable.log.wizard,model_receivable_log_wizard,base.group_user,1,1,1,1
|
||||
access_amount_way,amount_way,model_amount_way,base.group_user,1,1,1,1
|
||||
access_property_summary_report, property_summary_report,model_property_summary_report,base.group_user,1,1,1,1
|
||||
|
@@ -5,13 +5,17 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="应收列表" decoration-danger = "charge_status == 'unpaid'"
|
||||
decoration-muted="is_reconciliation == True"
|
||||
decoration-success="charge_status == 'fully_paid'">
|
||||
decoration-success="charge_status == 'fully_paid'" limit="20">
|
||||
<header>
|
||||
<button name="all_red" string="红冲" type="object" class="btn btn-primary"/>
|
||||
</header>
|
||||
<field name="property_id"/>
|
||||
<field name="lessee_id"/>
|
||||
<field name="management_type_id"/>
|
||||
<field name="due_date"/>
|
||||
<field name="original_amount"/>
|
||||
<field name="discount_amount"/>
|
||||
<field name="delivered1"/>
|
||||
<field name="submitted"/>
|
||||
<field name="charge_status" column_invisible="1"/>
|
||||
<field name="multiplier" column_invisible="1"/>
|
||||
@@ -24,10 +28,12 @@
|
||||
<field name="is_red" column_invisible="1"/>
|
||||
<field name="is_reconciliation" optional="hide"/>
|
||||
<field name="difference_amount"/>
|
||||
<field name="receivable_log" column_invisible="1"/>
|
||||
<field name="is_suspend" optional="hide"/>
|
||||
<button name="unlink" string="删除" type="object" class="oe_highlight"/>
|
||||
<button name="invalid" string="作废" type="object" class="oe_highlight"/>
|
||||
<button name="suspend" string="激活" type="object" class="oe_highlight" invisible="not is_suspend"/>
|
||||
<button name="unsuspend" string="挂起" type="object" class="oe_highlight" invisible="is_suspend"/>
|
||||
<button name="receivable_log_wizard" string="日志" type="object" class="oe_highlight"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -43,6 +49,16 @@
|
||||
<filter name="group_property_id" string="物业" context="{'group_by':'property_id'}"/>
|
||||
<filter name="group_lessee_id" string="承租方" context="{'group_by':'lessee_id'}"/>
|
||||
</group>
|
||||
<header_search>
|
||||
<quick_filter string="应收状态">
|
||||
<filter string="红冲" name="is_red" domain="[('is_red', '=', True)]"/>
|
||||
<filter string="开票" name="is_billing " domain="[('is_billing', '=', True)]"/>
|
||||
<filter string="对账" name="is_reconciliation" domain="[('is_reconciliation', '=', True)]"/>
|
||||
<filter string="未对账" name="not_reconciliation" domain="[('is_reconciliation', '=', False)]"/>
|
||||
<filter string="未开票" name="not_billing" domain="[('is_billing', '=', False)]"/>
|
||||
<filter string="作废" name="is_invalid" domain="[('is_invalid', '=', True)]"/>
|
||||
</quick_filter>
|
||||
</header_search>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
<field name="bank_branch" optional="hide"/>
|
||||
<field name="extract" optional="hide"/>
|
||||
<field name="account_code" optional="hide"/>
|
||||
<field name="is_put" column_invisible="1"/>
|
||||
<field name="remake"/>
|
||||
<field name="registered"/>
|
||||
<field name="original_amount"/>
|
||||
<field name="contract_account" optional="hide"/>
|
||||
<field name="contract_penalty" optional="hide"/>
|
||||
@@ -24,10 +24,10 @@
|
||||
<field name="bank_number" optional="hide"/>
|
||||
<field name="message" optional="hide"/>
|
||||
<field name="number" optional="hide"/>
|
||||
<field name="bank_state"/>
|
||||
<field name="voucher_type" optional="hide"/>
|
||||
<field name="is_reconciliation" column_invisible="1"/>
|
||||
<button name="put_button_cancel" type="object" string="退回" class="btn btn-primary"/>
|
||||
<button name="unlink" type="object" string="删除" class="btn btn-primary"/>
|
||||
<button name="binding_information" type="object" class="oe_highlight" string="绑定信息"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -36,6 +36,9 @@
|
||||
<field name="model">property.bank.statements</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="银行流水" editable="bottom" js_class="custom_bank_statements_button" limit="20">
|
||||
<!-- <header>-->
|
||||
<!-- <button name="handle_contract_penalty" type="object" class="oe_highlight" string="ce"/>-->
|
||||
<!-- </header>-->
|
||||
<field name="start_time"/>
|
||||
<field name="company_id" optional="hide"/>
|
||||
<field name="name"/>
|
||||
@@ -46,8 +49,8 @@
|
||||
<field name="bank_branch" optional="hide"/>
|
||||
<field name="extract" optional="hide"/>
|
||||
<field name="account_code" optional="hide"/>
|
||||
<field name="is_put" column_invisible="1"/>
|
||||
<field name="remake"/>
|
||||
<field name="registered"/>
|
||||
<field name="original_amount"/>
|
||||
<field name="contract_account" optional="hide"/>
|
||||
<field name="contract_penalty" optional="hide"/>
|
||||
@@ -55,9 +58,10 @@
|
||||
<field name="bank_number" optional="hide"/>
|
||||
<field name="message" optional="hide"/>
|
||||
<field name="number" optional="hide"/>
|
||||
<field name="bank_state"/>
|
||||
<field name="voucher_type" optional="hide"/>
|
||||
<field name="is_reconciliation" column_invisible="1"/>
|
||||
<button name="unlink" type="object" string="删除" class="btn btn-primary"/>
|
||||
<button name="other" type="object" string="其他" class="btn btn-primary"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -65,7 +69,7 @@
|
||||
<field name="name">对账</field>
|
||||
<field name="res_model">property.bank.statements</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('is_put', '=', True)]</field>
|
||||
<field name="domain">[('bank_state', '=', 'not_reconciled')]</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_bank_statements_tree')})]"/>
|
||||
</record>
|
||||
@@ -73,7 +77,7 @@
|
||||
<field name="name">银行流水</field>
|
||||
<field name="res_model">property.bank.statements</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('is_put', '=', False)]</field>
|
||||
<field name="context">{'group_by': 'bank_state'}</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_property.view_property_bank_statements_tree1')})]"/>
|
||||
</record>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<field name="name">property.tenant.information.form</field>
|
||||
<field name="model">property.tenant.information</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="承租方信息" create="0">
|
||||
<form string="承租方信息" create="0" limit="20">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
|
||||
@@ -4,3 +4,4 @@ from . import property_tenant_wizard
|
||||
from . import property_water_wizard
|
||||
from . import property_statements_wizard
|
||||
from . import evaluation_plan_wizard
|
||||
from . import receivable_log_wizard
|
||||
|
||||
@@ -120,6 +120,30 @@ class PropertyStatementsWizard(models.Model):
|
||||
'message':message,
|
||||
}
|
||||
if original_amount:
|
||||
self.env['property.bank.statements'].create(bank_data)
|
||||
statements = self.env['property.bank.statements'].create(bank_data)
|
||||
self._handle_contract_penalty(statements)
|
||||
else:
|
||||
pass
|
||||
pass
|
||||
|
||||
def _handle_contract_penalty(self, record):
|
||||
'''
|
||||
处理合同违约金
|
||||
:param record: property.bank.statements 记录
|
||||
:return:
|
||||
'''
|
||||
for contract_id in record.contract_ids:
|
||||
receivable_id = self.env['property.accounts.receivable'].search([('contract_id', '=', contract_id.id)])
|
||||
if receivable_id:
|
||||
dt = datetime.strptime(str(record.start_time), '%Y-%m-%d %H:%M:%S').date() # 流水交易时间
|
||||
due = datetime.strptime(str(receivable_id.due_date), '%Y-%m-%d').date() + relativedelta(months=1, day=1) # 应收日期
|
||||
# 判断是否违约
|
||||
if receivable_id.submitted and not receivable_id.is_reconciliation or not receivable_id.is_suspend:
|
||||
original_amount = (due - dt).days * receivable_id.original_amount * int(receivable_id.percentage_liquidated_damages.name)
|
||||
self.env['property.penalty.list'].create({
|
||||
'contract_id': contract_id.id,
|
||||
'property_id': contract_id.lease_ids[0].address_id.id,
|
||||
'lessee_id': contract_id.lessee_id.id,
|
||||
'original_amount': original_amount
|
||||
})
|
||||
receivable_id.write({'penalty':original_amount})
|
||||
receivable_id.is_reconciliation = True
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _, SUPERUSER_ID
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from pypinyin import pinyin, Style
|
||||
import xlrd
|
||||
import base64
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class ReceivableLogWizard(models.Model):
|
||||
_name = 'receivable.log.wizard'
|
||||
_description = '应收日志'
|
||||
|
||||
name = fields.Text(string='应收日志')
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="property_receivable_log_wizard_form" model="ir.ui.view">
|
||||
<field name="name">应收日志</field>
|
||||
<field name="model">receivable.log.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -3,6 +3,7 @@ from odoo.tools.float_utils import float_round
|
||||
from numpy.ma.core import default_filler
|
||||
from odoo import models, fields, api, exceptions, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
|
||||
class YuthonProperty(models.Model):
|
||||
@@ -39,7 +40,7 @@ class PropertyBankStatements(models.Model):
|
||||
for record in statements_ids:
|
||||
self._handle_contract_penalty(record)
|
||||
|
||||
|
||||
# 违约金计算
|
||||
def _handle_contract_penalty(self, record):
|
||||
'''
|
||||
处理合同违约金
|
||||
@@ -49,11 +50,11 @@ class PropertyBankStatements(models.Model):
|
||||
for contract_id in record.contract_ids:
|
||||
receivable_id = self.env['property.accounts.receivable'].search([('contract_id', '=', contract_id.id)])
|
||||
if receivable_id:
|
||||
dt = datetime.strptime(str(record.start_time), '%Y-%m-%d %H:%M:%S').date() # 对账日期
|
||||
due = datetime.strptime(str(receivable_id.due_date), '%Y-%m-%d').date() # 应收日期
|
||||
dt = datetime.strptime(str(record.start_time), '%Y-%m-%d %H:%M:%S').date() # 流水交易时间
|
||||
due = datetime.strptime(str(receivable_id.due_date), '%Y-%m-%d').date() + relativedelta(months=1, day=1) # 应收日期
|
||||
# 判断是否违约
|
||||
if receivable_id.due_date > record.start_time and not receivable_id.is_reconciliation or not receivable_id.is_suspend:
|
||||
original_amount = (due - dt).days * (receivable_id.original_amount - record.original_amount) * 0.001
|
||||
if receivable_id.submitted and not receivable_id.is_reconciliation or not receivable_id.is_suspend:
|
||||
original_amount = (due - dt).days * (receivable_id.original_amount - record.original_amount) * int(receivable_id.percentage_liquidated_damages.name)
|
||||
self.env['property.penalty.list'].create({
|
||||
'contract_id': contract_id.id,
|
||||
'property_id': contract_id.lease_ids[0].address_id.id,
|
||||
@@ -78,9 +79,6 @@ class PropertyBankStatements(models.Model):
|
||||
water_ids = self.env['property.water.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
# 应收电费
|
||||
electricity_ids = self.env['property.tariff.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
# 应收违约金
|
||||
penalty_ids = self.env['property.penalty.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
|
||||
|
||||
def create_reconciliation_vals(ids, collection_type_val):
|
||||
"""
|
||||
@@ -88,6 +86,17 @@ class PropertyBankStatements(models.Model):
|
||||
:param collection_type_val: 费用类型(如 'rent', 'deposit')
|
||||
:return: 格式化后的费用行列表
|
||||
"""
|
||||
collection_type_dict = {
|
||||
'deposit': '押金',
|
||||
'rent': '租金',
|
||||
'water_fee': '水费',
|
||||
'electricity_fee': '电费',
|
||||
'penalty': '违约',
|
||||
'management_fee': '管理费',
|
||||
'repair_fee': '维修费',
|
||||
'other': '其他'
|
||||
}
|
||||
|
||||
nonlocal total_rent_month
|
||||
vals_list = []
|
||||
# 特殊处理:押金类型需要去重相同合同的记录
|
||||
@@ -105,6 +114,11 @@ class PropertyBankStatements(models.Model):
|
||||
due_date = False
|
||||
if contract_id:
|
||||
due_date = sub_record.contract_id.actual_start_time
|
||||
management_type_id = self.env['yuthon.management.type'].search(
|
||||
[('name', '=', collection_type_dict[collection_type_val])], limit=1)
|
||||
accounts_id = self.env['property.accounts.receivable'].search(
|
||||
[('lessee_id', '=', tenant_id.id), ('due_date', '=', due_date),
|
||||
('management_type_id', '=', management_type_id.id)], limit=1)
|
||||
# 构建对账行数据
|
||||
vals = {
|
||||
'property_id': property_id,
|
||||
@@ -113,6 +127,7 @@ class PropertyBankStatements(models.Model):
|
||||
'rent': original_amount,
|
||||
'collection_type': collection_type_val,
|
||||
'due_date': due_date, # 押金类型使用合同实际开始日期
|
||||
'penalty': accounts_id.penalty if accounts_id else 0,
|
||||
}
|
||||
total_rent_month += original_amount # 累加总金额
|
||||
vals_list.append((0, 0, vals))
|
||||
@@ -126,6 +141,11 @@ class PropertyBankStatements(models.Model):
|
||||
contract_id = sub_record.contract_id.id if sub_record.contract_id else False
|
||||
original_amount = sub_record.original_amount if sub_record.original_amount else 0
|
||||
due_date = sub_record.due_date if sub_record.due_date else False
|
||||
management_type_id = self.env['yuthon.management.type'].search(
|
||||
[('name', '=', collection_type_dict[collection_type_val])], limit=1)
|
||||
accounts_id = self.env['property.accounts.receivable'].search(
|
||||
[('lessee_id', '=', tenant_id.id), ('due_date', '=', due_date),
|
||||
('management_type_id', '=', management_type_id.id)], limit=1)
|
||||
vals = {
|
||||
'property_id': property_id,
|
||||
'contract_id': contract_id,
|
||||
@@ -133,11 +153,11 @@ class PropertyBankStatements(models.Model):
|
||||
'rent': original_amount,
|
||||
'collection_type': collection_type_val,
|
||||
'due_date': due_date,
|
||||
'penalty': accounts_id.penalty if accounts_id else 0,
|
||||
}
|
||||
total_rent_month += original_amount # 累加总金额
|
||||
vals_list.append((0, 0, vals))
|
||||
|
||||
|
||||
return vals_list
|
||||
|
||||
all_vals = []
|
||||
@@ -158,6 +178,7 @@ class PropertyBankStatements(models.Model):
|
||||
:return:
|
||||
"""
|
||||
context = {
|
||||
"default_bank_id": self.id,
|
||||
"default_account": record.name,
|
||||
"default_actual_total": record.original_amount,
|
||||
"default_reconciliation_line_ids": all_vals,
|
||||
@@ -175,7 +196,6 @@ class PropertyBankStatements(models.Model):
|
||||
|
||||
def button_reconciliation(self):
|
||||
for record in self:
|
||||
self._handle_contract_penalty(record)
|
||||
all_vals, total_rent_month = self._get_reconciliation_vals(record)
|
||||
return self._get_context_and_action(record, all_vals, total_rent_month)
|
||||
|
||||
@@ -184,7 +204,6 @@ class PropertyBankStatements(models.Model):
|
||||
total_all_vals = []
|
||||
grand_total_rent_month = 0
|
||||
for record in statements_ids:
|
||||
self._handle_contract_penalty(record)
|
||||
all_vals, total_rent_month = self._get_reconciliation_vals(record)
|
||||
total_all_vals.extend(all_vals)
|
||||
grand_total_rent_month += total_rent_month
|
||||
|
||||
@@ -341,7 +341,7 @@
|
||||
<xpath expr="//field[@name='property_id']" position="after">
|
||||
<field name="contract_id" string="合同"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='difference_amount']" position="after">
|
||||
<xpath expr="//field[@name='receivable_log']" position="after">
|
||||
<field name="penalty"/>
|
||||
<field name="penalty_date"/>
|
||||
<button name="receivable_return" string="退回" class="btn-primary" type="object"/>
|
||||
@@ -390,9 +390,6 @@
|
||||
<xpath expr="//field[@name='property_ids']" position="before">
|
||||
<field name="contract_ids" string="合同编号" widget="many2many_tags"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='voucher_type']" position="after">
|
||||
<button name="put_button" type="object" string="推送" class="btn btn-primary"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="all_data_property_bank_statements" model="ir.actions.server">
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
<field name="bank_branch" optional="hide"/>
|
||||
<field name="extract" optional="hide"/>
|
||||
<field name="account_code" optional="hide"/>
|
||||
<field name="is_put" column_invisible="1"/>
|
||||
<field name="remake"/>
|
||||
<field name="original_amount"/>
|
||||
<field name="contract_account" optional="hide"/>
|
||||
|
||||
@@ -7,6 +7,7 @@ class PropertyReconciliationWizard(models.Model):
|
||||
_description = '对账弹窗'
|
||||
|
||||
receivable_total = fields.Float(string='应收金额')
|
||||
bank_id = fields.Many2one('property.bank.statements', string='银行流水')
|
||||
account = fields.Char(string='账号')
|
||||
actual_total = fields.Float(string='实收金额')
|
||||
initial_total = fields.Float(string='初始金额', default=0.0)
|
||||
@@ -19,20 +20,26 @@ class PropertyReconciliationWizard(models.Model):
|
||||
# 首次设置时记录初始值
|
||||
if not self.initial_total:
|
||||
self.initial_total = self.actual_total
|
||||
# 遍历明细行,按规则分配金额
|
||||
for index, line in enumerate(self.reconciliation_line_ids):
|
||||
if index == 0:
|
||||
# 第一行等于初始值
|
||||
line.amount = self.initial_total
|
||||
elif index == 1:
|
||||
# 第二行等于当前值减去初始值
|
||||
line.amount = max(0, self.actual_total - self.initial_total)
|
||||
|
||||
remaining_amount = self.actual_total
|
||||
|
||||
for line in self.reconciliation_line_ids:
|
||||
if remaining_amount <= 0:
|
||||
line.amount = 0 # 没有剩余金额,设为0
|
||||
else:
|
||||
# 第三行及以后:当前值 - (初始值 * 行号),但不小于0
|
||||
line.amount = max(0, self.actual_total - (self.initial_total * index))
|
||||
line.amount = min(self.initial_total, remaining_amount) # 分配初始值或剩余金额(取较小值)
|
||||
remaining_amount -= line.amount # 更新剩余金额
|
||||
|
||||
def confirm(self):
|
||||
pass
|
||||
for rec in self:
|
||||
if rec.actual_total> rec.receivable_total:
|
||||
rec.bank_id.registered = rec.actual_total - rec.receivable_total
|
||||
|
||||
receivable_ids = self.env['property.accounts.receivable'].search([('lessee_id.name', '=', self.bank_id.name_account)])
|
||||
for receivable in receivable_ids:
|
||||
receivable.write({'receivable_log': f'当前登录人{self.env.user.name}于{fields.Datetime.now()}对户名为{self.bank_id.name_account}进行对账操作,对账应收金额为{self.receivable_total}'
|
||||
f'实际金额为{self.actual_total}'})
|
||||
|
||||
|
||||
class PropertyReconciliationLine(models.Model):
|
||||
_name = 'property.reconciliation.line'
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="task_code_sequence" model="ir.sequence">
|
||||
<field name="name">日程编号</field>
|
||||
<field name="code">task_code</field>
|
||||
<field name="prefix">RC%(y)s%(month)s%(day)s</field>
|
||||
<field name="padding">3</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -67,6 +67,7 @@ class YuthonWillTask(models.Model):
|
||||
|
||||
priority = fields.Selection([('general', '不紧急不重要'), ('important', '重要不紧急'),
|
||||
('urgent', '紧急不重要'), ('very_urgent', '重要且紧急')], string='优先级')
|
||||
code = fields.Char(string="任务编号", default=lambda self: self.env['ir.sequence'].next_by_code('task_code'))
|
||||
user_id = fields.Many2one('res.users', string="创建人", default=lambda self: self.env.user)
|
||||
company_id = fields.Many2one('res.company', string="公司", default=lambda self: self.env.company)
|
||||
task_content = fields.Text(string='任务内容')
|
||||
|
||||
@@ -47,12 +47,29 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="日程">
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="重要不紧急" bg_color="text-bg-success"
|
||||
invisible="priority != 'important'"/>
|
||||
<widget name="web_ribbon" title="紧急不重要" bg_color="text-bg-warning"
|
||||
invisible="priority != 'urgent'"/>
|
||||
<widget name="web_ribbon" title="重要且紧急" bg_color="text-bg-danger"
|
||||
invisible="priority != 'very_urgent'"/>
|
||||
<group col="3">
|
||||
<group>
|
||||
<field name="code" string="流水号" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="priority" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<div class="oe_title">
|
||||
<label for="task_content"/>
|
||||
<h1>
|
||||
<field name="task_content" required="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="task_time_ids"/>
|
||||
</group>
|
||||
<group>
|
||||
<label for="start_date"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
@@ -68,22 +85,14 @@
|
||||
<field name="user_id"/>
|
||||
<field name="task_state" invisible="1"/>
|
||||
<field name="employee_ids" widget="many2many_tags" options="{'no_create': True}"/>
|
||||
<field name='employee_ids2' widget="many2many_tags" domain="[('user_role_ids.name', 'in', ['司机'])]"/>
|
||||
<field name="user_role_ids" widget="many2many_tags" invisible="1"/>
|
||||
<field name='users_ids' widget="many2many_tags" invisible="1"/>
|
||||
<field name='employee_ids2' widget="many2many_tags" domain="[('user_role_ids.name', 'in', ['司机'])]"/>
|
||||
<field name="address"/>
|
||||
<field name="remarks"/>
|
||||
<field name='document_ids' widget="preview_many2many"/>
|
||||
<field name="creation_time" invisible="1"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="priority"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="task_time_ids" widget="many2many_tags" required="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" groups="base.group_user" options="{'post_refresh': 'recipients'}"/>
|
||||
|
||||
Reference in New Issue
Block a user