!12907 添加功能

Merge pull request !12907 from dev_zhou
This commit is contained in:
李鹏宇
2026-09-22 10:49:56 +00:00
committed by Gitee
3 changed files with 58 additions and 37 deletions
@@ -60,6 +60,11 @@ class PropertyAccountsReceivable(models.Model):
has_date = fields.Date(string='退款日期')
delivered = fields.Boolean()
submitted = fields.Float(string='未收', compute='compute_submitted', store=True)
# 欠费月数 = 当前日期 - 应收开始日期(按整月计,未到期为 0);不落库,随算随出
overdue_months = fields.Integer(string='欠费月数', compute='_compute_overdue_months',
help='当前日期 - 应收开始日期,按整月计算;未到期为 0')
# 列表徽章展示用,形如「47 个月」
overdue_months_display = fields.Char(string='欠费月数', compute='_compute_overdue_months')
is_invalid = fields.Boolean(string='作废')
void_date = fields.Date(string='作废日期')
is_red = fields.Boolean(string='红冲')
@@ -278,6 +283,20 @@ class PropertyAccountsReceivable(models.Model):
else:
record.submitted = 0
@api.depends('due_date')
def _compute_overdue_months(self):
today = fields.Date.context_today(self)
for record in self:
months = 0
if record.due_date:
delta = relativedelta(today, record.due_date)
months = delta.years * 12 + delta.months
if months < 0:
months = 0
record.overdue_months = months
# 未到期(0)时留空,列表里的徽章自动隐藏
record.overdue_months_display = ('%s 个月' % months) if months > 0 else ''
def initialize_wizard(self):
return {
'name': '应收账单初始化数据弹窗',
@@ -511,40 +511,14 @@
<field name="name">property.accounts.receivable.tree.contract</field>
<field name="model">property.accounts.receivable</field>
<field name="inherit_id" ref="yuthon_property.view_property_accounts_receivable_tree"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<!-- primary 独立视图:自动继承基础 tree 的最终效果(含 form_tree 已有字段/按钮),
这里只改默认排序;不能再重复挂那些字段/按钮继承,否则会与
inherit_property_accounts_receivable_form_tree 叠加导致列与按钮出现两遍。 -->
<xpath expr="//tree" position="attributes">
<attribute name="default_order">due_date desc</attribute>
</xpath>
<xpath expr="//tree" position="inside">
<header>
<button name="all_red" string="红冲" type="object" class="btn btn-primary"/>
<button name="update_lessee_id" string="更新" type="object" class="btn btn-primary"/>
<button name="action_fix" string="修复关联" type="object" class="btn btn-primary"/>
</header>
</xpath>
<xpath expr="//button[@name='receivable_log_wizard']" position="before">
<field name="penalty_ratio_value" string="违约金比例" readonly="1" optional="show"/>
<button name="penalty_wizard" string="收款明细" type="object" class="btn btn-blue" invisible="is_penalty"/>
<button name="button_accounts_wizard" string="操作" type="object" class="btn btn-blue"/>
</xpath>
<xpath expr="//field[@name='remark']" position="after">
<field name="charging_range"/>
<field name="is_penalty" column_invisible="1"/>
<field name="property_name" width="350px"/>
<field name="property_ids" options="{'no_create': True}" widget="many2many_tags" column_invisible="1"/>
<field name="lessee_id" options="{'no_create': True}" readonly="1"/>
<field name="title_deed" readonly="1"/>
<field name="company_id" column_invisible="1"/>
<field name="last_month_table" column_invisible="1"/>
<field name="this_month_table" column_invisible="1"/>
<field name="ratio" column_invisible="1"/>
<field name="billable_quantity" column_invisible="1"/>
<field name="contract_id" string="合同编号" context="{'form_view_ref': 'yuthon_property_approval.view_property_lease_contract_form1'}"/>
</xpath>
<xpath expr="//field[@name='receivable_log']" position="after">
<field name="penalty"/>
<field name="penalty_date"/>
</xpath>
</field>
</record>
<record id="property_accounts_receivable_contract_action" model="ir.actions.act_window">
@@ -94,15 +94,43 @@
作用:类型专属菜单里已经用 domain 限定了类型,列表里不再显示「应收类型」列
说明:mode=primary 使其成为独立视图,不影响「应收账单汇总」等原有菜单的视图
-->
<!-- 类型子菜单专用精简列表视图:只保留指定列(状态/应收开始/应收结束/收款日期/当前金额/减免金额/未收金额/欠费月数/承租方/合同编号/物业/备注),
欠费月数(overdue_months_display) = 当前日期 - 应收开始日期,badge 徽章样式;
按钮保留(表头:红冲/更新/修复关联;行内:收款明细/操作/日志)。
独立视图(不再继承基础 tree),避免基础 tree 的字段/按钮叠加。 -->
<record id="view_receivable_type_tree_no_type" model="ir.ui.view">
<field name="name">property.accounts.receivable.tree.no.type</field>
<field name="model">property.accounts.receivable</field>
<field name="inherit_id" ref="yuthon_property.view_property_accounts_receivable_tree"/>
<field name="inherit_id" eval="False"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<field name="management_type_id" position="attributes">
<attribute name="column_invisible">1</attribute>
</field>
<tree editable="bottom" string="应收账单" default_order="due_date desc" limit="15" delete="false">
<header>
<button name="all_red" string="红冲" type="object" class="btn btn-primary"/>
<button name="update_lessee_id" string="更新" type="object" class="btn btn-primary"/>
<button name="action_fix" string="修复关联" type="object" class="btn btn-primary"/>
</header>
<field name="deposit_state"/>
<field name="due_date"/>
<field name="due_date_end"/>
<field name="payout_date"/>
<field name="original_amount"/>
<field name="discount_amount"/>
<field name="submitted" string="未收金额"/>
<!-- 欠费月数 = 当前日期 - 应收开始日期;badge 徽章样式(欠费时红色) -->
<field name="overdue_months" column_invisible="1"/>
<field name="overdue_months_display" string="欠费月数" widget="badge"
decoration-danger="overdue_months > 0"/>
<field name="lessee_id"/>
<field name="contract_id"/>
<field name="property_name"/>
<field name="remark"/>
<!-- 仅在行的按钮里使用,不作为列显示 -->
<field name="is_penalty" column_invisible="1"/>
<button name="penalty_wizard" string="收款明细" type="object" class="btn btn-blue" invisible="is_penalty"/>
<button name="button_accounts_wizard" string="操作" type="object" class="btn btn-blue"/>
<button name="receivable_log_wizard" string="日志" type="object" class="btn btn-blue"/>
</tree>
</field>
</record>
@@ -292,8 +320,8 @@
<field name="context">{'group_by': 'management_type_id', 'orderedBy': [{'name': 'due_date', 'asc': False}], 'searchpanel_default_deposit_state': 'unpaid'}</field>
<!-- 使用本模块专用的搜索视图(含 searchpanel) -->
<field name="search_view_id" ref="yuthon_work_brand.view_receivable_type_search"/>
<!-- 本菜单需按应收类型分组、必须显示该列,故复用应收账单原有列表视图(不隐藏应收类型列) -->
<field name="view_id" ref="yuthon_property.view_property_accounts_receivable_tree"/>
<!-- 与其余类型子菜单保持一致:使用精简列表视图(12 列,无按钮) -->
<field name="view_id" ref="yuthon_work_brand.view_receivable_type_tree_no_type"/>
</record>
<menuitem id="menu_receivable_type_others"
name="其他"
@@ -484,7 +512,7 @@ action = {'type': 'ir.actions.act_window', 'name': '灯箱', 'res_model': 'prope
employee = env['hr.employee'].search([('user_id', '=', env.user.id)], limit=1)
precinct = env['yuthon.precinct.message'].search([('employee_id', '=', employee.id)], limit=1) if employee else env['yuthon.precinct.message']
domain = [('management_type_id.name', 'in', ['广告灯箱费', '有偿服务收入', '停车费', '管子间', '更名费', '维修费', '其他费用', '评估费', '保险费'])]
view_id = env.ref('yuthon_property.view_property_accounts_receivable_tree').id
view_id = env.ref('yuthon_work_brand.view_receivable_type_tree_no_type').id
ctx = {'group_by': 'management_type_id', 'orderedBy': [{'name': 'due_date', 'asc': False}], 'searchpanel_default_deposit_state': 'unpaid'}
if precinct:
ctx['searchpanel_default_precinct_id'] = precinct.id