!10059 !10058 Merge branch 'dev' of <a href="https://gitee.com/jinan-pengyuse…

Merge pull request !10059 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2026-03-21 11:49:10 +00:00
committed by Gitee
4 changed files with 125 additions and 20 deletions
+34 -6
View File
@@ -36,6 +36,9 @@ class ReceivableFlowReport(models.Model):
condition = params.get('condition')
partner_id = params.get('partner_id')
company_id = params.get('company_id')
property_id = params.get('property_id')
lessee_id = params.get('lessee_id')
contract_id = params.get('contract_id')
if condition:
domain.append(('tenure_type', '=', condition))
@@ -43,6 +46,12 @@ class ReceivableFlowReport(models.Model):
domain.append(('precinct_id', '=', partner_id))
if company_id:
domain.append(('company_id', '=', company_id))
if property_id:
domain.append(('property_ids', 'in', [property_id]))
if lessee_id:
domain.append(('lessee_id', '=', lessee_id))
if contract_id:
domain.append(('contract_id', '=', contract_id))
receivables = self.sudo().search(domain, order="id asc")
rec_ids = receivables.ids
@@ -209,8 +218,18 @@ class ReceivableFlowReport(models.Model):
"序号": idx,
"租金id": rec.id,
"应收日期": rec.due_date.strftime("%Y-%m-%d") if rec.due_date else "",
"应收金额": round(rec.original_amount, 2),
"收款总金额": round(total_collected, 2),
"应收金额": {
'model': 'property.accounts.receivable',
'display_name': str(round(rec.original_amount, 2)),
'view_mode': 'tree',
'domain': [('id', '=', rec.id)],
},
"收款总金额": {
'model': 'receivable.modify.line',
'display_name': str(round(total_collected, 2)),
'view_mode': 'tree',
'domain': [('receivable_id', '=', rec.id), ('reconciliation_date', '!=', False)],
},
"未收": round(rec.submitted, 2),
"收款金额": round(payment_amount, 2),
"收款时间": payment_date.strftime("%Y-%m-%d") if payment_date else "",
@@ -218,7 +237,12 @@ class ReceivableFlowReport(models.Model):
"状态": charge_status,
"违约金计算时间": billing_period,
"违约天数": days_diff,
"违约金金额": round(penalty_amount, 2),
"违约金金额": {
'model': 'property.accounts.receivable',
'display_name': str(round(penalty_amount, 2)),
'view_mode': 'tree',
'domain': [('id', '=', rec.id)],
},
"违约金收款时间": penalty_payment_date.strftime("%Y-%m-%d") if penalty_payment_date else "",
"违约金收款金额": round(total_penalty_collected, 2),
"合同编号": {
@@ -226,7 +250,11 @@ class ReceivableFlowReport(models.Model):
'id': rec.contract_id.id if rec.contract_id else None,
'display_name': rec.contract_id.contract_code if rec.contract_id else "",
} if rec.contract_id else "",
"物业名称": rec.property_name or "",
"物业名称": {
'model': 'yuthon.property',
'id': rec.contract_id.lease_ids[0].address_id.id if rec.contract_id and rec.contract_id.lease_ids and rec.contract_id.lease_ids[0].address_id else None,
'display_name': rec.property_name or "",
} if rec.contract_id and rec.contract_id.lease_ids and rec.contract_id.lease_ids[0].address_id else rec.property_name or "",
"承租方名称": {
'model': 'property.tenant.information',
'id': rec.lessee_id.id if rec.lessee_id else None,
@@ -236,8 +264,8 @@ class ReceivableFlowReport(models.Model):
stats = [
{'name': '记录总数', 'amount': len(rows)},
{'name': '应收总额', 'amount': round(sum(row["应收金额"] for row in rows), 2)},
{'name': '已收总额', 'amount': round(sum(row["收款总金额"] for row in rows), 2)},
{'name': '应收总额', 'amount': round(sum(float(row["应收金额"]['display_name']) for row in rows), 2)},
{'name': '已收总额', 'amount': round(sum(float(row["收款总金额"]['display_name']) for row in rows), 2)},
{'name': '未收总额', 'amount': round(sum(row["未收"] for row in rows), 2)},
]
@@ -33,6 +33,9 @@ class ReceivableReport extends Component {
selectPartner: {},
selectCompany: {},
selectManagementType: {},
selectProperty: {},
selectLessee: {},
selectContract: {},
condition: false,
conditions: [
{'name': '', 'value': ''},
@@ -142,13 +145,15 @@ class ReceivableReport extends Component {
* 穿透渲染器:将对象格式的字段渲染为可点击的链接
* 如果字段值是对象(包含 model、id、display_name),则渲染为可点击链接
* 否则直接显示原值
* 支持 view_mode: 'tree' + domain 打开 tree 弹窗
* 支持 view_mode: 'form' 或默认打开 form 弹窗
*/
linkRender(params) {
if (!params.value) return '';
// 如果是对象格式(包含 model 和 id),渲染为可点击链接
if (typeof params.value === 'object' && params.value.model && params.value.id) {
const { model, id, display_name } = params.value;
// 如果是对象格式(包含 model),渲染为可点击链接
if (typeof params.value === 'object' && params.value.model) {
const { model, id, display_name, view_mode, domain, view_id } = params.value;
const el = document.createElement('div');
el.className = 'o_record_cell';
@@ -156,13 +161,25 @@ class ReceivableReport extends Component {
el.classList.add('btn');
el.classList.add('btn-link');
el.onclick = () => {
params.context.actionService.doAction({
type: 'ir.actions.act_window',
res_model: model,
res_id: id,
views: [[false, 'form'], [false, 'search']],
target: 'new'
});
if (view_mode === 'tree') {
// tree 弹窗:用 domain 过滤多条记录
params.context.actionService.doAction({
type: 'ir.actions.act_window',
res_model: model,
views: [[view_id || false, 'tree']],
domain: domain || [],
target: 'new',
});
} else {
// form 弹窗:打开单条记录
params.context.actionService.doAction({
type: 'ir.actions.act_window',
res_model: model,
res_id: id,
views: [[false, 'form'], [false, 'search']],
target: 'new'
});
}
};
return el;
@@ -292,6 +309,9 @@ class ReceivableReport extends Component {
partner_id: this.state.selectPartner?.id,
company_id: this.state.selectCompany?.id,
management_type_id: this.state.selectManagementType?.id || false,
property_id: this.state.selectProperty?.id || false,
lessee_id: this.state.selectLessee?.id || false,
contract_id: this.state.selectContract?.id || false,
};
} else {
let startDate = formatDate(this.state.startDate, {format: "yyyy-MM-dd"})
@@ -304,6 +324,9 @@ class ReceivableReport extends Component {
partner_id: this.state.selectPartner?.id,
company_id: this.state.selectCompany?.id,
management_type_id: this.state.selectManagementType?.id || false,
property_id: this.state.selectProperty?.id || false,
lessee_id: this.state.selectLessee?.id || false,
contract_id: this.state.selectContract?.id || false,
};
}
const result = await this.serviceOrm.call(
@@ -376,6 +399,21 @@ class ReceivableReport extends Component {
this._applyManagementTypeFilter();
}
async onUpdateProperty(v) {
this.state.selectProperty = v[0] || {};
await this.onSearch();
}
async onUpdateLessee(v) {
this.state.selectLessee = v[0] || {};
await this.onSearch();
}
async onUpdateContract(v) {
this.state.selectContract = v[0] || {};
await this.onSearch();
}
_applyManagementTypeFilter() {
if (!this.grid) return;
const typeName = this.state.selectManagementType?.display_name || '';
@@ -109,6 +109,45 @@
/>
</div>
<!-- 物业名称 -->
<div class="col">
<Many2XAutocomplete
value="state.selectProperty?.display_name"
getDomain="getDomainCompany"
resModel="'yuthon.property'"
fieldString="'物业名称'"
placeholder="'物业名称'"
activeActions="{}"
update.bind="onUpdateProperty"
/>
</div>
<!-- 承租方 -->
<div class="col">
<Many2XAutocomplete
value="state.selectLessee?.display_name"
getDomain="getDomainCompany"
resModel="'property.tenant.information'"
fieldString="'承租方'"
placeholder="'承租方'"
activeActions="{}"
update.bind="onUpdateLessee"
/>
</div>
<!-- 合同编号 -->
<div class="col">
<Many2XAutocomplete
value="state.selectContract?.display_name"
getDomain="getDomainCompany"
resModel="'property.lease.contract'"
fieldString="'合同编号'"
placeholder="'合同编号'"
activeActions="{}"
update.bind="onUpdateContract"
/>
</div>
<!-- 操作按钮 -->
<div class="col-auto">
<button class="btn btn-success" t-on-click="onExportExcel">导出</button>
@@ -14,11 +14,11 @@
{"headerName": "序号", "field": "序号", "width": 45, "flex": 0, "pinned": "left"},
{"headerName": "租金id", "field": "租金id", "flex": 1},
{"headerName": "合同编号", "field": "合同编号", "flex": 1.2},
{"headerName": "物业名称", "field": "物业名称", "flex": 2},
{"headerName": "物业名称", "field": "物业名称", "flex": 2, "cellRenderer": "linkRender"},
{"headerName": "承租方名称", "field": "承租方名称", "flex": 1.4},
{"headerName": "应收日期", "field": "应收日期", "flex": 1},
{"headerName": "应收金额", "field": "应收金额", "flex": 1, "type": "number"},
{"headerName": "收款总金额", "field": "收款总金额", "flex": 1, "type": "number"},
{"headerName": "应收金额", "field": "应收金额", "flex": 1, "type": "number", "cellRenderer": "linkRender"},
{"headerName": "收款总金额", "field": "收款总金额", "flex": 1, "type": "number", "cellRenderer": "linkRender"},
{"headerName": "未收", "field": "未收", "flex": 1, "type": "number"},
{"headerName": "收款金额", "field": "收款金额", "flex": 1, "type": "number"},
{"headerName": "收款时间", "field": "收款时间", "flex": 1},
@@ -26,7 +26,7 @@
{"headerName": "状态", "field": "状态", "flex": 1},
{"headerName": "违约金计算时间", "field": "违约金计算时间", "flex": 2.5, "wrapText": true},
{"headerName": "违约天数", "field": "违约天数", "flex": 1, "type": "number"},
{"headerName": "违约金金额", "field": "违约金金额", "flex": 1, "type": "number"},
{"headerName": "违约金金额", "field": "违约金金额", "flex": 1, "type": "number", "cellRenderer": "linkRender"},
{"headerName": "违约金收款时间", "field": "违约金收款时间", "flex": 1},
{"headerName": "违约金收款金额", "field": "违约金收款金额", "flex": 1, "type": "number"}
]