diff --git a/yuthon_report/__manifest__.py b/yuthon_report/__manifest__.py index e5a6183d8..de75cdcfb 100644 --- a/yuthon_report/__manifest__.py +++ b/yuthon_report/__manifest__.py @@ -75,6 +75,8 @@ 'yuthon_report/static/src/components/yuthon_report/receivable_message.xml', 'yuthon_report/static/src/components/yuthon_report/yuthon_report.scss', 'yuthon_report/static/src/components/yuthon_report/receivable_report.js', + 'yuthon_report/static/src/components/yuthon_report/multi_select_autocomplete.js', + 'yuthon_report/static/src/components/yuthon_report/multi_select_autocomplete.xml', 'yuthon_report/static/src/components/yuthon_report/receivable_report.xml', 'yuthon_report/static/src/components/yuthon_report/receivable_flow_report.js', 'yuthon_report/static/src/components/yuthon_report/text_summary_report.js', diff --git a/yuthon_report/models/__init__.py b/yuthon_report/models/__init__.py index 494e0d0e8..425f095ec 100644 --- a/yuthon_report/models/__init__.py +++ b/yuthon_report/models/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from . import report_utils from . import res_partner from . import ledger_report from . import receivable_report diff --git a/yuthon_report/models/assessment_fee_monthly_report.py b/yuthon_report/models/assessment_fee_monthly_report.py index 8c0611fa0..3a922c3bd 100644 --- a/yuthon_report/models/assessment_fee_monthly_report.py +++ b/yuthon_report/models/assessment_fee_monthly_report.py @@ -3,6 +3,7 @@ import calendar import logging from odoo import api, models +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) @@ -55,14 +56,14 @@ class PropertyBillsList(models.Model): ] # 公司/片区过滤 - company_id = params.get('company_id') - partner_id = params.get('partner_id') + company_id = _id_list(params.get('company_id')) + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) if company_id: - domain.append(('lessor_id', '=', int(company_id))) + domain.append(('lessor_id', 'in', company_id)) if partner_id: domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), # 合同片区过滤(多选支持) + ('receivables_id.precinct_id', 'in', partner_id), # 应收记录片区过滤(多选支持) ] # 查询记录 diff --git a/yuthon_report/models/assessment_fee_yearly_report.py b/yuthon_report/models/assessment_fee_yearly_report.py index 0d5e1beb2..bdfc5d630 100644 --- a/yuthon_report/models/assessment_fee_yearly_report.py +++ b/yuthon_report/models/assessment_fee_yearly_report.py @@ -3,6 +3,7 @@ import calendar import logging from odoo import api, models +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) @@ -55,14 +56,14 @@ class PropertyBillsList(models.Model): ] # 公司/片区过滤 - company_id = params.get('company_id') - partner_id = params.get('partner_id') + company_id = _id_list(params.get('company_id')) + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) if company_id: - domain.append(('lessor_id', '=', int(company_id))) + domain.append(('lessor_id', 'in', company_id)) if partner_id: domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), # 合同片区过滤(多选支持) + ('receivables_id.precinct_id', 'in', partner_id), # 应收记录片区过滤(多选支持) ] # 查询记录 diff --git a/yuthon_report/models/att_report.py b/yuthon_report/models/att_report.py index 609214a9b..a628dd67f 100644 --- a/yuthon_report/models/att_report.py +++ b/yuthon_report/models/att_report.py @@ -1,5 +1,6 @@ import datetime +from .report_utils import _id_list from odoo import fields, models, api @@ -16,7 +17,7 @@ class AttendanceReport(models.Model): vacation_domain.append(("vacation_date", "<=", date_end)) salary_group_id = params.get('structure_id', False) department_id = params.get('department_id', False) - company_id = params.get('company_id', False) + company_id = _id_list(params.get('company_id', False)) employee_domain = [] if salary_group_id: @@ -24,7 +25,7 @@ class AttendanceReport(models.Model): if department_id: employee_domain.append(('department_id', '=', department_id)) if company_id: - employee_domain.append(('company_id', '=', company_id)) + employee_domain.append(('company_id', 'in', company_id)) employee_ids = [] if employee_domain: @@ -146,11 +147,13 @@ class AttendanceReport(models.Model): @api.model def get_domain(self, company_id=False): - if not company_id: + # 多选:company_id 标准化为列表 + cid_list = _id_list(company_id) + if not cid_list: return [], [] - department_records = self.env['hr.department'].search([('company_id', '=', company_id)]) + department_records = self.env['hr.department'].search([('company_id', 'in', cid_list)]) department_ids = [dept.id for dept in department_records] - salary_group_records = self.env['yuthon.salary.group'].search([('company_id', '=', company_id)]) + salary_group_records = self.env['yuthon.salary.group'].search([('company_id', 'in', cid_list)]) salary_group_ids = [struct.id for struct in salary_group_records] return department_ids, salary_group_ids diff --git a/yuthon_report/models/bank_statements_report.py b/yuthon_report/models/bank_statements_report.py index a72ec988f..11c1fc6ad 100644 --- a/yuthon_report/models/bank_statements_report.py +++ b/yuthon_report/models/bank_statements_report.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from .report_utils import _id_list from odoo import api, models @@ -23,9 +24,9 @@ class BankStatementsReport(models.Model): domain.append(('lending_direction', '=', 'loan')) # 公司搜索条件 - company_id = params.get('company_id') + company_id = _id_list(params.get('company_id')) if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) # 账号单位搜索条件 your_own_unit = params.get('your_own_unit') diff --git a/yuthon_report/models/cum_arrears_report.py b/yuthon_report/models/cum_arrears_report.py index 0360f83b8..c3b891548 100644 --- a/yuthon_report/models/cum_arrears_report.py +++ b/yuthon_report/models/cum_arrears_report.py @@ -2,6 +2,7 @@ import calendar import datetime from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class CumArrearsReport(models.Model): @@ -50,8 +51,8 @@ class CumArrearsReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -60,9 +61,9 @@ class CumArrearsReport(models.Model): if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + domain.append(('receivable_id.precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if property_id: domain.append(('receivable_id.property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/cum_income_report.py b/yuthon_report/models/cum_income_report.py index 2c46d64fb..d5bf42a49 100644 --- a/yuthon_report/models/cum_income_report.py +++ b/yuthon_report/models/cum_income_report.py @@ -2,6 +2,7 @@ import calendar import datetime from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class CumIncomeReport(models.Model): @@ -52,16 +53,16 @@ class CumIncomeReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + domain.append(('receivable_id.precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if management_type_id: domain.append(('receivable_id.management_type_id', '=', management_type_id)) else: diff --git a/yuthon_report/models/current_month_received_report.py b/yuthon_report/models/current_month_received_report.py index ae5246af2..894f89c69 100644 --- a/yuthon_report/models/current_month_received_report.py +++ b/yuthon_report/models/current_month_received_report.py @@ -1,6 +1,7 @@ import datetime from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class CurrentMonthReceivedReport(models.Model): @@ -39,8 +40,8 @@ class CurrentMonthReceivedReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -49,9 +50,9 @@ class CurrentMonthReceivedReport(models.Model): if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + domain.append(('receivable_id.precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if property_id: domain.append(('receivable_id.property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/current_receivable_property_fee_report.py b/yuthon_report/models/current_receivable_property_fee_report.py index 1006def31..987ee601f 100644 --- a/yuthon_report/models/current_receivable_property_fee_report.py +++ b/yuthon_report/models/current_receivable_property_fee_report.py @@ -1,6 +1,7 @@ import datetime from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class CurrentReceivablePropertyFeeReport(models.Model): @@ -36,16 +37,16 @@ class CurrentReceivablePropertyFeeReport(models.Model): domain.append(("due_date", "<=", end_dt)) condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if management_type_id: domain.append(('management_type_id', '=', management_type_id)) diff --git a/yuthon_report/models/deposit_cum_arrears_report.py b/yuthon_report/models/deposit_cum_arrears_report.py index 1f54dbcac..1d540e6f7 100644 --- a/yuthon_report/models/deposit_cum_arrears_report.py +++ b/yuthon_report/models/deposit_cum_arrears_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class DepositCumArrearsReport(models.Model): @@ -49,17 +50,17 @@ class DepositCumArrearsReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(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)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: @@ -142,13 +143,13 @@ class DepositCumArrearsReport(models.Model): ('is_invalid', '!=', True), ] - company_id = params.get('company_id') + company_id = _id_list(params.get('company_id')) property_id = params.get('property_id') lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/deposit_month_receivable_report.py b/yuthon_report/models/deposit_month_receivable_report.py index d703226cd..c02275e07 100644 --- a/yuthon_report/models/deposit_month_receivable_report.py +++ b/yuthon_report/models/deposit_month_receivable_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class DepositMonthReceivableReport(models.Model): @@ -39,14 +40,14 @@ class DepositMonthReceivableReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) lines = self.sudo().search(domain, order="contract_id asc") diff --git a/yuthon_report/models/deposit_month_received_report.py b/yuthon_report/models/deposit_month_received_report.py index 41c5993db..11515a967 100644 --- a/yuthon_report/models/deposit_month_received_report.py +++ b/yuthon_report/models/deposit_month_received_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class DepositMonthReceivedReport(models.Model): @@ -44,17 +45,17 @@ class DepositMonthReceivedReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(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)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: @@ -141,13 +142,13 @@ class DepositMonthReceivedReport(models.Model): ('is_invalid', '!=', True), ] - company_id = params.get('company_id') + company_id = _id_list(params.get('company_id')) property_id = params.get('property_id') lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/deposit_month_refund_report.py b/yuthon_report/models/deposit_month_refund_report.py index 2fcd339c2..96960c141 100644 --- a/yuthon_report/models/deposit_month_refund_report.py +++ b/yuthon_report/models/deposit_month_refund_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class DepositMonthRefundReport(models.Model): @@ -42,8 +43,8 @@ class DepositMonthRefundReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -51,9 +52,9 @@ class DepositMonthRefundReport(models.Model): if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/deposit_pre_received_report.py b/yuthon_report/models/deposit_pre_received_report.py index 97c6373ea..30ed0ba45 100644 --- a/yuthon_report/models/deposit_pre_received_report.py +++ b/yuthon_report/models/deposit_pre_received_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class DepositPreReceivedReport(models.Model): @@ -44,17 +45,17 @@ class DepositPreReceivedReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(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)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: @@ -157,13 +158,13 @@ class DepositPreReceivedReport(models.Model): ('is_invalid', '!=', True), ] - company_id = params.get('company_id') + company_id = _id_list(params.get('company_id')) property_id = params.get('property_id') lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/deposit_total_report.py b/yuthon_report/models/deposit_total_report.py index 71180e047..0a2d5322a 100644 --- a/yuthon_report/models/deposit_total_report.py +++ b/yuthon_report/models/deposit_total_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class DepositTotalReport(models.Model): @@ -59,8 +60,8 @@ class DepositTotalReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -68,9 +69,9 @@ class DepositTotalReport(models.Model): if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/leased_area_report.py b/yuthon_report/models/leased_area_report.py index 62eab111a..dc4587a53 100644 --- a/yuthon_report/models/leased_area_report.py +++ b/yuthon_report/models/leased_area_report.py @@ -3,6 +3,7 @@ import datetime import logging from odoo import api, models +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) @@ -41,8 +42,8 @@ class LeasedAreaReport(models.Model): keyword = params.get("keyword") condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) + company_id = _id_list(params.get('company_id')) # 前端侧边栏下拉选择器传入的 ID property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -202,7 +203,7 @@ class LeasedAreaReport(models.Model): matched = False for cl in lines: ml = manage_map.get(cl.address_id.id) if cl.address_id else None - if ml and ml.precinct_id and ml.precinct_id.id == int(partner_id): + if ml and ml.precinct_id and ml.precinct_id.id in partner_id: # 片区匹配(多选支持) matched = True break if not matched: @@ -211,7 +212,7 @@ class LeasedAreaReport(models.Model): matched = False for cl in lines: ml = manage_map.get(cl.address_id.id) if cl.address_id else None - if ml and ml.company_id and ml.company_id.id == int(company_id): + if ml and ml.company_id and ml.company_id.id in company_id: matched = True break if not matched: diff --git a/yuthon_report/models/ledger_report.py b/yuthon_report/models/ledger_report.py index 497005e9f..c27991b79 100644 --- a/yuthon_report/models/ledger_report.py +++ b/yuthon_report/models/ledger_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import fields, models, api +from .report_utils import _id_list # partner_id 多选适配工具 class YuthonProperty(models.Model): @@ -32,16 +33,16 @@ class YuthonProperty(models.Model): # 基础过滤条件 condition = params.get('condition', False) - partner_id = params.get('partner_id', False) - company_id = params.get('company_id', False) + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id', False)) domain = [] if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) properties = self.search(domain, limit=500) diff --git a/yuthon_report/models/maintenance_fee_monthly_report.py b/yuthon_report/models/maintenance_fee_monthly_report.py index 114a7f364..15b5c3537 100644 --- a/yuthon_report/models/maintenance_fee_monthly_report.py +++ b/yuthon_report/models/maintenance_fee_monthly_report.py @@ -3,6 +3,7 @@ import calendar import logging from odoo import api, models +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) @@ -55,14 +56,14 @@ class PropertyBillsList(models.Model): ] # 公司/片区过滤 - company_id = params.get('company_id') - partner_id = params.get('partner_id') + company_id = _id_list(params.get('company_id')) + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) if company_id: - domain.append(('lessor_id', '=', int(company_id))) + domain.append(('lessor_id', 'in', company_id)) if partner_id: domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), # 合同片区过滤(多选支持) + ('receivables_id.precinct_id', 'in', partner_id), # 应收记录片区过滤(多选支持) ] # 查询记录 diff --git a/yuthon_report/models/maintenance_fee_yearly_report.py b/yuthon_report/models/maintenance_fee_yearly_report.py index 7f2e2cd0f..b915ac4d6 100644 --- a/yuthon_report/models/maintenance_fee_yearly_report.py +++ b/yuthon_report/models/maintenance_fee_yearly_report.py @@ -3,6 +3,7 @@ import calendar import logging from odoo import api, models +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) @@ -55,14 +56,14 @@ class PropertyBillsList(models.Model): ] # 公司/片区过滤 - company_id = params.get('company_id') - partner_id = params.get('partner_id') + company_id = _id_list(params.get('company_id')) + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) if company_id: - domain.append(('lessor_id', '=', int(company_id))) + domain.append(('lessor_id', 'in', company_id)) if partner_id: domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), # 合同片区过滤(多选支持) + ('receivables_id.precinct_id', 'in', partner_id), # 应收记录片区过滤(多选支持) ] # 查询记录 diff --git a/yuthon_report/models/management_area_report.py b/yuthon_report/models/management_area_report.py index c1b53645d..d409d17cf 100644 --- a/yuthon_report/models/management_area_report.py +++ b/yuthon_report/models/management_area_report.py @@ -2,6 +2,7 @@ import datetime import logging from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 _logger = logging.getLogger(__name__) @@ -33,8 +34,8 @@ class ManagementAreaReport(models.Model): keyword = params.get("keyword") condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) # 前端侧边栏下拉选择器传入的 ID property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -65,9 +66,9 @@ class ManagementAreaReport(models.Model): if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) # 物业名称下拉选择器:直接过滤 yuthon_property_id if property_id: domain.append(('yuthon_property_id', '=', int(property_id))) diff --git a/yuthon_report/models/management_fee_monthly_report.py b/yuthon_report/models/management_fee_monthly_report.py index 8c3da4ef1..20ae5804e 100644 --- a/yuthon_report/models/management_fee_monthly_report.py +++ b/yuthon_report/models/management_fee_monthly_report.py @@ -3,6 +3,7 @@ import calendar import logging from odoo import api, models +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) @@ -55,14 +56,14 @@ class PropertyBillsList(models.Model): ] # 公司/片区过滤 - company_id = params.get('company_id') - partner_id = params.get('partner_id') + company_id = _id_list(params.get('company_id')) + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) if company_id: - domain.append(('lessor_id', '=', int(company_id))) + domain.append(('lessor_id', 'in', company_id)) if partner_id: domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), # 合同片区过滤(多选支持) + ('receivables_id.precinct_id', 'in', partner_id), # 应收记录片区过滤(多选支持) ] # 查询记录 diff --git a/yuthon_report/models/management_fee_yearly_report.py b/yuthon_report/models/management_fee_yearly_report.py index de6a17fc0..9874a5e57 100644 --- a/yuthon_report/models/management_fee_yearly_report.py +++ b/yuthon_report/models/management_fee_yearly_report.py @@ -3,6 +3,7 @@ import calendar import logging from odoo import api, models +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) @@ -55,14 +56,14 @@ class PropertyBillsList(models.Model): ] # 公司/片区过滤 - company_id = params.get('company_id') - partner_id = params.get('partner_id') + company_id = _id_list(params.get('company_id')) + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) if company_id: - domain.append(('lessor_id', '=', int(company_id))) + domain.append(('lessor_id', 'in', company_id)) if partner_id: domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), # 合同片区过滤(多选支持) + ('receivables_id.precinct_id', 'in', partner_id), # 应收记录片区过滤(多选支持) ] # 查询记录 diff --git a/yuthon_report/models/month_receivable_report.py b/yuthon_report/models/month_receivable_report.py index 5c8455ea5..10ee8ea5b 100644 --- a/yuthon_report/models/month_receivable_report.py +++ b/yuthon_report/models/month_receivable_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class MonthReceivableReport(models.Model): @@ -38,8 +39,8 @@ class MonthReceivableReport(models.Model): ('receivable_id.contract_id.contract_code', 'ilike', keyword)] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -48,9 +49,9 @@ class MonthReceivableReport(models.Model): if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + domain.append(('receivable_id.precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if property_id: domain.append(('receivable_id.property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/monthly_precollection_report.py b/yuthon_report/models/monthly_precollection_report.py index d02ec33b4..5ef11be41 100644 --- a/yuthon_report/models/monthly_precollection_report.py +++ b/yuthon_report/models/monthly_precollection_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class MonthlyPrecollectionReport(models.Model): @@ -43,8 +44,8 @@ class MonthlyPrecollectionReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -53,9 +54,9 @@ class MonthlyPrecollectionReport(models.Model): if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + domain.append(('receivable_id.precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if property_id: domain.append(('receivable_id.property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/parking_fee_current_month_receivable.py b/yuthon_report/models/parking_fee_current_month_receivable.py index fb737e261..06d96eb1e 100644 --- a/yuthon_report/models/parking_fee_current_month_receivable.py +++ b/yuthon_report/models/parking_fee_current_month_receivable.py @@ -1,6 +1,7 @@ import datetime from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class ParkingFeeCurrentMonthReceivable(models.Model): @@ -46,16 +47,16 @@ class ParkingFeeCurrentMonthReceivable(models.Model): # 其他过滤 condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) # 管理类型 if management_type_id: diff --git a/yuthon_report/models/parking_fee_current_month_report.py b/yuthon_report/models/parking_fee_current_month_report.py index e4a82d17c..5a6951c26 100644 --- a/yuthon_report/models/parking_fee_current_month_report.py +++ b/yuthon_report/models/parking_fee_current_month_report.py @@ -1,6 +1,7 @@ import datetime from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class ParkingFeeCurrentMonthReport(models.Model): @@ -41,16 +42,16 @@ class ParkingFeeCurrentMonthReport(models.Model): end_dt = datetime.datetime.fromisoformat(date_end).date() if date_end else month_end condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) # 管理类型 if management_type_id: diff --git a/yuthon_report/models/parking_fee_yearly_report.py b/yuthon_report/models/parking_fee_yearly_report.py index da3389de1..58c7735ab 100644 --- a/yuthon_report/models/parking_fee_yearly_report.py +++ b/yuthon_report/models/parking_fee_yearly_report.py @@ -1,6 +1,7 @@ import datetime from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 class ParkingFeeYearlyReport(models.Model): @@ -42,16 +43,16 @@ class ParkingFeeYearlyReport(models.Model): # 过滤条件 condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if management_type_id: domain.append(('management_type_id', '=', management_type_id)) diff --git a/yuthon_report/models/penalty_arrears_report.py b/yuthon_report/models/penalty_arrears_report.py index 43b2f5a4c..1e978c7c7 100644 --- a/yuthon_report/models/penalty_arrears_report.py +++ b/yuthon_report/models/penalty_arrears_report.py @@ -2,6 +2,7 @@ import datetime # 日期时间处理模块,用于日期解析、计算、格 import logging # 日志模块,用于调试输出 from odoo import api, models # Odoo 核心 API:api 装饰器、models 模型基类 +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) # 获取当前模块的日志记录器 @@ -42,8 +43,8 @@ class PenaltyArrearsReport(models.Model): # ========== 二、构建公共筛选条件 ========== keyword = params.get("keyword") # 关键字搜索 condition = params.get('condition') # 租赁类型 - partner_id = params.get('partner_id') # 片区 ID - company_id = params.get('company_id') # 公司 ID + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) + company_id = _id_list(params.get('company_id')) # 公司 ID property_id = params.get('property_id') # 物业 ID lessee_id = params.get('lessee_id') # 承租方 ID contract_id = params.get('contract_id') # 合同 ID @@ -64,9 +65,9 @@ class PenaltyArrearsReport(models.Model): return False if condition and rec.tenure_type != condition: return False - if partner_id and rec.precinct_id.id != int(partner_id): + if partner_id and rec.precinct_id.id not in partner_id: # 片区过滤(多选支持) return False - if company_id and rec.company_id.id != int(company_id): + if company_id and rec.company_id.id not in company_id: return False if property_id and int(property_id) not in (rec.property_ids.ids or []): return False diff --git a/yuthon_report/models/penalty_month_received_report.py b/yuthon_report/models/penalty_month_received_report.py index 5e9915009..4e37228b2 100644 --- a/yuthon_report/models/penalty_month_received_report.py +++ b/yuthon_report/models/penalty_month_received_report.py @@ -3,6 +3,7 @@ import logging # 日志模块,用于调试输出 import re # 正则表达式模块,用于解析收费区间字符串 from odoo import api, models # Odoo 核心 API:api 装饰器、models 模型基类 +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) # 获取当前模块的日志记录器 @@ -42,8 +43,8 @@ class PenaltyMonthReceivedReport(models.Model): # 其他筛选条件参数 keyword = params.get("keyword") condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) + company_id = _id_list(params.get('company_id')) property_id = params.get('property_id') lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') @@ -64,9 +65,9 @@ class PenaltyMonthReceivedReport(models.Model): return False if condition and rec.tenure_type != condition: return False - if partner_id and rec.precinct_id.id != int(partner_id): + if partner_id and rec.precinct_id.id not in partner_id: # 片区过滤(多选支持) return False - if company_id and rec.company_id.id != int(company_id): + if company_id and rec.company_id.id not in company_id: return False if property_id and int(property_id) not in (rec.property_ids.ids or []): return False @@ -90,9 +91,9 @@ class PenaltyMonthReceivedReport(models.Model): match = True if not match: return False - if partner_id and ml.precinct_id and ml.precinct_id.id != int(partner_id): + if partner_id and ml.precinct_id and ml.precinct_id.id not in partner_id: # modify.line 片区过滤(多选支持) return False - if company_id and ml.company_id and ml.company_id.id != int(company_id): + if company_id and ml.company_id and ml.company_id.id not in company_id: return False if lessee_id and (not ml.lessee_id or ml.lessee_id.id != int(lessee_id)): return False diff --git a/yuthon_report/models/penalty_year_cum_report.py b/yuthon_report/models/penalty_year_cum_report.py index 4fc19c3b5..f417a5810 100644 --- a/yuthon_report/models/penalty_year_cum_report.py +++ b/yuthon_report/models/penalty_year_cum_report.py @@ -3,6 +3,7 @@ import logging # 日志模块,用于调试输出 import re # 正则表达式模块,用于解析收费区间字符串 from odoo import api, models # Odoo 核心 API:api 装饰器、models 模型基类 +from .report_utils import _id_list # 导入 ID 列表解析工具函数,支持多选参数 _logger = logging.getLogger(__name__) # 获取当前模块的日志记录器 @@ -44,8 +45,8 @@ class PenaltyYearCumReport(models.Model): # 其他筛选条件参数 keyword = params.get("keyword") condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 解析片区 ID 为整数列表(多选支持) + company_id = _id_list(params.get('company_id')) property_id = params.get('property_id') lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') @@ -66,9 +67,9 @@ class PenaltyYearCumReport(models.Model): return False if condition and rec.tenure_type != condition: return False - if partner_id and rec.precinct_id.id != int(partner_id): + if partner_id and rec.precinct_id.id not in partner_id: # 片区过滤(多选支持) return False - if company_id and rec.company_id.id != int(company_id): + if company_id and rec.company_id.id not in company_id: return False if property_id and int(property_id) not in (rec.property_ids.ids or []): return False @@ -92,9 +93,9 @@ class PenaltyYearCumReport(models.Model): match = True if not match: return False - if partner_id and ml.precinct_id and ml.precinct_id.id != int(partner_id): + if partner_id and ml.precinct_id and ml.precinct_id.id not in partner_id: # modify.line 片区过滤(多选支持) return False - if company_id and ml.company_id and ml.company_id.id != int(company_id): + if company_id and ml.company_id and ml.company_id.id not in company_id: return False if lessee_id and (not ml.lessee_id or ml.lessee_id.id != int(lessee_id)): return False diff --git a/yuthon_report/models/pre_advance_report.py b/yuthon_report/models/pre_advance_report.py index b051ee6c8..012c59121 100644 --- a/yuthon_report/models/pre_advance_report.py +++ b/yuthon_report/models/pre_advance_report.py @@ -1,6 +1,7 @@ import datetime from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class PreAdvanceReport(models.Model): @@ -50,8 +51,8 @@ class PreAdvanceReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -60,9 +61,9 @@ class PreAdvanceReport(models.Model): if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + domain.append(('receivable_id.precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if property_id: domain.append(('receivable_id.property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/pre_arrears_report.py b/yuthon_report/models/pre_arrears_report.py index 5f65ba133..b6d13a49b 100644 --- a/yuthon_report/models/pre_arrears_report.py +++ b/yuthon_report/models/pre_arrears_report.py @@ -2,6 +2,7 @@ import datetime import logging from odoo import api, models +from .report_utils import _id_list _logger = logging.getLogger(__name__) @@ -40,8 +41,9 @@ class PreArrearsReport(models.Model): # 提取筛选参数 keyword = params.get("keyword") condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + # 多选标准化:partner_id 统一为列表 + partner_id = _id_list(params.get('partner_id')) + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -67,9 +69,10 @@ class PreArrearsReport(models.Model): if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + # 多选:片区管理员用 'in' 操作符 + domain.append(('receivable_id.precinct_id', 'in', partner_id)) if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if property_id: domain.append(('receivable_id.property_ids', 'in', [property_id])) if lessee_id: @@ -151,9 +154,10 @@ class PreArrearsReport(models.Model): if condition: receivable_domain.append(('tenure_type', '=', condition)) if partner_id: - receivable_domain.append(('precinct_id', '=', partner_id)) + # 多选:片区管理员用 'in' 操作符 + receivable_domain.append(('precinct_id', 'in', partner_id)) if company_id: - receivable_domain.append(('company_id', '=', company_id)) + receivable_domain.append(('company_id', 'in', company_id)) if property_id: receivable_domain.append(('property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/receivable_flow_report.py b/yuthon_report/models/receivable_flow_report.py index 491395485..9b2f103de 100644 --- a/yuthon_report/models/receivable_flow_report.py +++ b/yuthon_report/models/receivable_flow_report.py @@ -2,6 +2,7 @@ import datetime import re from odoo import api, models +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class ReceivableFlowReport(models.Model): @@ -20,13 +21,13 @@ class ReceivableFlowReport(models.Model): ('is_invalid', '!=', True), ] - company_id = params.get('company_id') + company_id = _id_list(params.get('company_id')) property_id = params.get('property_id') lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: @@ -74,8 +75,8 @@ class ReceivableFlowReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id')) property_id = params.get('property_id') lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') @@ -83,9 +84,9 @@ class ReceivableFlowReport(models.Model): if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) if property_id: domain.append(('property_ids', 'in', [property_id])) if lessee_id: diff --git a/yuthon_report/models/receivable_report.py b/yuthon_report/models/receivable_report.py index bf915c926..1377fb648 100644 --- a/yuthon_report/models/receivable_report.py +++ b/yuthon_report/models/receivable_report.py @@ -1,6 +1,7 @@ import datetime from odoo import fields, models, api +from .report_utils import _id_list # 导入工具函数:将参数转换为列表格式,支持多选筛选 class YuthonProperty(models.Model): @@ -63,15 +64,15 @@ class YuthonProperty(models.Model): domain.append(("due_date", "<=", date_end)) condition = params.get('condition', False) - partner_id = params.get('partner_id', False) - company_id = params.get('company_id', False) + partner_id = _id_list(params.get('partner_id', False)) # 将partner_id转换为列表,用于多选筛选 + company_id = _id_list(params.get('company_id', False)) if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 使用in操作符支持多选片区筛选 if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) receivables = self.search(domain, order="contract_id asc, due_date asc") @@ -163,11 +164,13 @@ class YuthonProperty(models.Model): def get_domain(self, start_date=False, end_date=False, company_id=False): if not start_date or not end_date: return [] - if not company_id: + # 多选:company_id 标准化为列表 + cid_list = _id_list(company_id) + if not cid_list: return [] - # 这里进行条件的修改 - property_records = self.env['yuthon.property'].search([('company_id', '=', company_id)]) + # 按公司ID列表查询物业,获取片区管理员ID集合 + property_records = self.env['yuthon.property'].search([('company_id', 'in', cid_list)]) user_ids = set() for property_record in property_records: diff --git a/yuthon_report/models/rent_area_report.py b/yuthon_report/models/rent_area_report.py index 753198181..1155060db 100644 --- a/yuthon_report/models/rent_area_report.py +++ b/yuthon_report/models/rent_area_report.py @@ -2,6 +2,7 @@ import datetime import logging from odoo import api, models +from .report_utils import _id_list # partner_id 多选适配工具 _logger = logging.getLogger(__name__) @@ -33,8 +34,8 @@ class RentAreaReport(models.Model): keyword = params.get("keyword") condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + partner_id = _id_list(params.get('partner_id')) # 支持多选,转为列表 + company_id = _id_list(params.get('company_id')) # 前端侧边栏下拉选择器传入的 ID property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -64,9 +65,9 @@ class RentAreaReport(models.Model): if condition: domain.append(('tenure_type', '=', condition)) if partner_id: - domain.append(('precinct_id', '=', partner_id)) + domain.append(('precinct_id', 'in', partner_id)) # 多选用 in if company_id: - domain.append(('company_id', '=', company_id)) + domain.append(('company_id', 'in', company_id)) # 物业名称下拉选择器:直接过滤 yuthon_property_id if property_id: domain.append(('yuthon_property_id', '=', int(property_id))) diff --git a/yuthon_report/models/report_utils.py b/yuthon_report/models/report_utils.py new file mode 100644 index 000000000..d2c2c420d --- /dev/null +++ b/yuthon_report/models/report_utils.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +"""报表公共工具函数""" +import logging + +_logger = logging.getLogger(__name__) + + +def _id_list(val): + """将参数标准化为扁平整数列表,用于多选场景下 'in' 操作符 + + - 列表/元组 → 递归展平后返回列表(防止 [[20, 30]] 嵌套导致 SQL 类型错误) + - 单个整数 → [val] + - None/False/0/空字符串 → [](空列表,使 if partner_id 为 False,不追加条件) + + 单选时 _id_list(20) → [20],配合 'in' [20] 等价于原来的 = 20,数据一致 + 多选时 _id_list([20, 30]) → [20, 30],配合 'in' [20, 30] 正常 + 嵌套时 _id_list([[20, 30]]) → [20, 30],防止 psycopg2 把 list 转为 ARRAY 导致 SQL 类型错误 + """ + if isinstance(val, (list, tuple)): + result = [] + for item in val: + # 递归展平嵌套的列表/元组 + if isinstance(item, (list, tuple)): + result.extend(_id_list(item)) + elif item is not None and item is not False and item != 0 and item != '': + result.append(item) + return result + if val is None or val is False or val == 0 or val == '': + return [] + return [val] diff --git a/yuthon_report/models/staff_position_report.py b/yuthon_report/models/staff_position_report.py index a2ed7705b..01716414b 100644 --- a/yuthon_report/models/staff_position_report.py +++ b/yuthon_report/models/staff_position_report.py @@ -1,3 +1,4 @@ +from .report_utils import _id_list from odoo import api, models from datetime import datetime from dateutil.relativedelta import relativedelta @@ -15,7 +16,7 @@ class StaffPositionReport(models.Model): # 不再过滤is_enable和establishment_quotas,查询所有岗位 domain = [] - company_id = params.get("company_id") + company_id = _id_list(params.get('company_id')) department_id = params.get("department_id") keyword = params.get("keyword") date_end = params.get("date_end") # 获取截止日期 diff --git a/yuthon_report/models/text_summary_report.py b/yuthon_report/models/text_summary_report.py index fe00f0664..4ad5f110e 100644 --- a/yuthon_report/models/text_summary_report.py +++ b/yuthon_report/models/text_summary_report.py @@ -2,6 +2,7 @@ import datetime import calendar +from .report_utils import _id_list from odoo import api, models @@ -31,7 +32,7 @@ class TextSummaryReport(models.Model): query_date = today # 获取筛选条件 - company_id = params.get('company_id') + company_id = _id_list(params.get('company_id')) precinct_id = params.get('partner_id') # 构建报表数据结构 diff --git a/yuthon_report/models/total_received_report.py b/yuthon_report/models/total_received_report.py index 38b9f38df..acaced3b5 100644 --- a/yuthon_report/models/total_received_report.py +++ b/yuthon_report/models/total_received_report.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import api, models +from .report_utils import _id_list class TotalReceivedReport(models.Model): @@ -38,8 +39,9 @@ class TotalReceivedReport(models.Model): ] condition = params.get('condition') - partner_id = params.get('partner_id') - company_id = params.get('company_id') + # 多选标准化:partner_id 统一为列表,配合 'in' 操作符 + partner_id = _id_list(params.get('partner_id')) + company_id = _id_list(params.get('company_id')) management_type_id = params.get('management_type_id') property_id = params.get('property_id') lessee_id = params.get('lessee_id') @@ -47,10 +49,11 @@ class TotalReceivedReport(models.Model): if condition: domain.append(('receivable_id.tenure_type', '=', condition)) + # 片区管理员:多选,用 'in' 操作符 if partner_id: - domain.append(('receivable_id.precinct_id', '=', partner_id)) + domain.append(('receivable_id.precinct_id', 'in', partner_id)) if company_id: - domain.append(('receivable_id.company_id', '=', company_id)) + domain.append(('receivable_id.company_id', 'in', company_id)) if management_type_id: domain.append(('receivable_id.management_type_id', '=', management_type_id)) if property_id: diff --git a/yuthon_report/models/yuthon_dashboard.py b/yuthon_report/models/yuthon_dashboard.py index 9601ba4de..3d47d8772 100644 --- a/yuthon_report/models/yuthon_dashboard.py +++ b/yuthon_report/models/yuthon_dashboard.py @@ -4,6 +4,7 @@ import calendar import logging from odoo import api, models +from .report_utils import _id_list _logger = logging.getLogger(__name__) @@ -150,6 +151,7 @@ class YuthonDashboard(models.Model): # ==================== 汇总信息 ==================== filters = { '统计时间': f"{query_date.year}-{query_date.month:02d}", + # 多选:所属公司传ID列表 '所属公司': self._get_company_display(params.get('company_id')), '管理员': self._get_admin_display(params.get('partner_id')), } @@ -157,10 +159,12 @@ class YuthonDashboard(models.Model): # ==================== 构建筛选条件上下文(透传给子报表) ==================== # 子报表从 action.context.dashboard_filter 中读取并初始化筛选状态 # date_str: "YYYY-MM" 格式,子报表据此还原 DateTime 对象 + # 多选:company_id/partner_id 透传ID列表,名称拼接 + cid_list = _id_list(params.get('company_id')) dashboard_filter = { 'date_str': f"{query_date.year}-{query_date.month:02d}" if has_date else '', - 'company_id': params.get('company_id') or False, - 'company_name': self._get_company_display(params.get('company_id')) if params.get('company_id') else '', + 'company_id': cid_list or False, + 'company_name': self._get_company_display(params.get('company_id')) if cid_list else '', 'partner_id': params.get('partner_id') or False, 'partner_name': self._get_admin_display(params.get('partner_id')) if params.get('partner_id') else '', 'condition': params.get('condition') or '', @@ -276,24 +280,40 @@ class YuthonDashboard(models.Model): # ------------------------------------------------------- def _get_company_display(self, company_id): + """根据公司ID列表获取公司显示名(多选支持) + company_id 是 yuthon.property.company 的 ID 列表(多选)或单值 + """ if not company_id: return '全部' try: - company = self.env['yuthon.property.company'].browse(int(company_id)) - return company.name if company else '未知' + # 多选:company_id 是列表,获取所有名称用逗号拼接 + cid_list = _id_list(company_id) + if not cid_list: + return '全部' + companies = self.env['yuthon.property.company'].browse(cid_list) + names = [c.name for c in companies if c.name] + return ', '.join(names) if names else '未知' except Exception: return '未知' def _get_admin_display(self, partner_id): - """根据片区ID获取管理员显示名 - partner_id 是 yuthon.precinct.message 的 ID(前端 Many2XAutocomplete 绑定该模型) + """根据片区ID列表获取管理员显示名(多选支持) + partner_id 是 yuthon.precinct.message 的 ID 列表(多选)或单值 display_name 已自动拼接为 "{片区名称}{管理员姓名}",如 "二B梁嘉辉" """ if not partner_id: return '全部' try: - precinct = self.env['yuthon.precinct.message'].browse(int(partner_id)) - return precinct.display_name if precinct else '未知' + # 多选:partner_id 是列表,获取所有名称用逗号拼接 + pid_list = _id_list(partner_id) + if not pid_list: + return '全部' + names = [] + for pid in pid_list: + precinct = self.env['yuthon.precinct.message'].browse(pid) + if precinct: + names.append(precinct.display_name) + return '、'.join(names) if names else '未知' except Exception: return '未知' @@ -304,8 +324,9 @@ class YuthonDashboard(models.Model): last_day = calendar.monthrange(query_date.year, query_date.month)[1] month_last = query_date.replace(day=last_day) - company_id = base_params.get('company_id') - partner_id = base_params.get('partner_id') + company_id = _id_list(base_params.get('company_id')) + # 多选标准化:partner_id 统一为列表 + partner_id = _id_list(base_params.get('partner_id')) keyword = base_params.get('keyword') # 按费用类型分别统计(数据源:property.bills.list) @@ -323,11 +344,12 @@ class YuthonDashboard(models.Model): ('actual_date', '<=', month_last), ] if company_id: - domain.append(('lessor_id', '=', int(company_id))) + domain.append(('lessor_id', 'in', company_id)) if partner_id: + # 多选:片区管理员用 'in' 操作符 domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), + ('receivables_id.precinct_id', 'in', partner_id), ] if keyword: domain += ['|', '|', '|', @@ -347,11 +369,12 @@ class YuthonDashboard(models.Model): ('actual_date', '<=', month_last), ] if company_id: - year_domain.append(('lessor_id', '=', int(company_id))) + year_domain.append(('lessor_id', 'in', company_id)) if partner_id: + # 多选:片区管理员用 'in' 操作符 year_domain += ['|', - ('contract_id.precinct_id', '=', int(partner_id)), - ('receivables_id.precinct_id', '=', int(partner_id)), + ('contract_id.precinct_id', 'in', partner_id), + ('receivables_id.precinct_id', 'in', partner_id), ] year_records = self.env['property.bills.list'].sudo().search(year_domain) year_total = sum((r.amount_actual or 0.0) for r in year_records) diff --git a/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.js b/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.js index 8b101fc11..2cf9991ed 100644 --- a/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.js +++ b/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.js @@ -5,6 +5,7 @@ import { Component, onMounted, useState } from "@odoo/owl"; import { useService } from "@web/core/utils/hooks"; import { standardActionServiceProps } from "@web/webclient/actions/action_service"; import { Many2XAutocomplete } from "@web/views/fields/relational_utils"; +import { MultiSelectAutocomplete } from "../yuthon_report/multi_select_autocomplete"; class YuthonDashboard extends Component { setup() { @@ -18,8 +19,10 @@ class YuthonDashboard extends Component { loading: false, collapsedSections: {}, // 筛选器 - selectCompany: {}, - selectPartner: {}, + // 多选:所属公司改为数组 + selectCompany: [], + // 多选:片区管理员改为数组 + selectPartner: [], condition: "", conditions: [ { name: "", value: "" }, @@ -37,12 +40,15 @@ class YuthonDashboard extends Component { const cached = sessionStorage.getItem("yuthon_dashboard_cache"); if (cached) { const snapshot = JSON.parse(cached); + // 从缓存恢复时,selectCompany/selectPartner 必须是数组, + // 旧格式({})或非数组值一律回退为空数组,防止 .map() 报错 + const safeArr = (val) => (Array.isArray(val) ? val : []); Object.assign(this.state, { dateStart: snapshot.dateStart || this.state.dateStart, - selectCompany: snapshot.selectCompany || this.state.selectCompany, - selectPartner: snapshot.selectPartner || this.state.selectPartner, + selectCompany: safeArr(snapshot.selectCompany), + selectPartner: safeArr(snapshot.selectPartner), condition: snapshot.condition || this.state.condition, - domainUsers: snapshot.domainUsers || this.state.domainUsers, + domainUsers: safeArr(snapshot.domainUsers), dashboardData: snapshot.dashboardData || this.state.dashboardData, collapsedSections: snapshot.collapsedSections || this.state.collapsedSections, }); @@ -86,8 +92,8 @@ class YuthonDashboard extends Component { } getDomain() { - const isCompanyEmpty = Object.keys(this.state.selectCompany).length === 0; - if (isCompanyEmpty) { + // 多选:检查公司数组是否为空 + if (!this.state.selectCompany.length) { return []; } else { return [["id", "in", this.state.domainUsers]]; @@ -95,7 +101,8 @@ class YuthonDashboard extends Component { } async searchUserDomain() { - this.state.selectPartner = {}; + // 多选:重置片区管理员为空数组 + this.state.selectPartner = []; // get_domain 需要 start_date 和 end_date,否则直接返回 [] // 从当前选择的月份推算,没选月份就用当月 @@ -115,6 +122,8 @@ class YuthonDashboard extends Component { endDate = `${y}-${m}-${String(lastDay).padStart(2, "0")}`; } + // 多选:传公司ID列表 + const companyIdList = this.state.selectCompany.map(item => item.id); const results = await this.serviceOrm.call( "property.accounts.receivable", "get_domain", @@ -122,33 +131,28 @@ class YuthonDashboard extends Component { { start_date: startDate, end_date: endDate, - company_id: this.state.selectCompany?.id, + company_id: companyIdList, } ); this.state.domainUsers = results || []; } - async onUpdateCompany(v) { - if (!v || !v[0]) { - this.state.selectCompany = {}; - this.state.selectPartner = {}; - this.state.domainUsers = []; - await this.onSearch(); - return; + async onUpdateCompany(items) { + // 多选:items 是已选项数组 [{id, display_name}, ...] + this.state.selectCompany = items; + // 多选:片区管理员重置为空数组 + this.state.selectPartner = []; + this.state.domainUsers = []; + // 有公司选中时才查询domain + if (items.length) { + await this.searchUserDomain(); } - const values = await this.serviceOrm.call( - "yuthon.property.company", - "read", - [[v[0].id]], - { fields: ["display_name"] } - ); - this.state.selectCompany = values[0] || {}; - await this.searchUserDomain(); await this.onSearch(); } - async onUpdatePartner(v) { - this.state.selectPartner = v[0] || {}; + async onUpdatePartner(items) { + // 多选:items 是已选项数组 [{id, display_name}, ...] + this.state.selectPartner = items; await this.onSearch(); } @@ -164,8 +168,10 @@ class YuthonDashboard extends Component { const params = { date_start: this.state.dateStart, keyword: this.state.keyword, - company_id: this.state.selectCompany?.id || false, - partner_id: this.state.selectPartner?.id || false, + // 多选:所属公司传ID列表 + company_id: this.state.selectCompany.map(item => item.id), + // 多选:片区管理员传ID列表 + partner_id: this.state.selectPartner.map(item => item.id), condition: this.state.condition || false, }; @@ -205,10 +211,12 @@ class YuthonDashboard extends Component { // 构建当前看板的筛选参数,透传给子报表 const dashboardFilter = { date_str: this.state.dateStart || "", // "YYYY-MM" - company_id: this.state.selectCompany?.id || false, - company_name: this.state.selectCompany?.display_name || "", - partner_id: this.state.selectPartner?.id || false, - partner_name: this.state.selectPartner?.display_name || "", + // 多选:所属公司传ID列表和名称拼接 + company_id: this.state.selectCompany.map(item => item.id), + company_name: this.state.selectCompany.map(item => item.display_name).join(", "), + // 多选:片区管理员传ID列表和名称拼接 + partner_id: this.state.selectPartner.map(item => item.id), + partner_name: this.state.selectPartner.map(item => item.display_name).join(", "), condition: this.state.condition || "", }; @@ -247,6 +255,7 @@ YuthonDashboard.props = { ...standardActionServiceProps }; YuthonDashboard.template = "yuthon_dashboard.YuthonDashboard"; YuthonDashboard.components = { Many2XAutocomplete, + MultiSelectAutocomplete, }; registry.category("actions").add("yuthon_dashboard_client", YuthonDashboard); diff --git a/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.xml b/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.xml index 5858b47c2..d0af935b0 100644 --- a/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.xml +++ b/yuthon_report/static/src/components/yuthon_dashboard/yuthon_dashboard.xml @@ -18,14 +18,15 @@