From 6b66836aa94bbcbdac07c5bb00b24923d5430407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Wed, 10 Jun 2026 11:23:45 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=8A=A5=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/deposit_cum_arrears_report.py | 65 +++++++++++++++-- .../models/deposit_month_received_report.py | 69 +++++++++++++++++-- .../models/deposit_pre_received_report.py | 6 +- 3 files changed, 125 insertions(+), 15 deletions(-) diff --git a/yuthon_report/models/deposit_cum_arrears_report.py b/yuthon_report/models/deposit_cum_arrears_report.py index d7fed7801..516372a64 100644 --- a/yuthon_report/models/deposit_cum_arrears_report.py +++ b/yuthon_report/models/deposit_cum_arrears_report.py @@ -14,9 +14,11 @@ class DepositCumArrearsReport(models.Model): - 数据源:property.accounts.receivable - 管理费用类型为"押金" - 非作废记录 - - 应收日期(due_date)在查询月内(包含查询月) - - 有欠收金额(submitted > 0) - 金额:submitted(未收金额) + - 状态取数逻辑(放宽 domain + 内存过滤): + - 未收(unpaid)/收部分(no_paid):due_date 存在且 <= 查询月末(应收日期在查询月及之前,到期未收) + - 已收(paid):payout_date > 查询月末 → 查询时点上尚未收款,应计入欠收 + payout_date <= 查询月末 → 查询时点时已收到,不计入欠收 """ date_start = params.get("date_start") query_date = datetime.datetime.fromisoformat(date_start).date() if date_start else datetime.date.today() @@ -24,12 +26,11 @@ class DepositCumArrearsReport(models.Model): last_day = calendar.monthrange(query_date.year, query_date.month)[1] month_last = query_date.replace(day=last_day) + # 放宽 domain,只做基础筛选 domain = [ ('management_type_id.name', '=', '押金'), ('is_invalid', '!=', True), - ('due_date', '>=', month_first), - ('due_date', '<=', month_last), - ('submitted', '>', 0), + ('deposit_state', 'in', ['unpaid', 'no_paid', 'paid']), ] keyword = params.get("keyword") @@ -43,15 +44,35 @@ class DepositCumArrearsReport(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)) if partner_id: 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)) lines = self.sudo().search(domain, order="contract_id asc") + # 内存过滤:按状态分别处理 + # - 未收(unpaid)/收部分(no_paid):due_date 存在且 <= 查询月末(到期未收) + # - 已收(paid):payout_date > 查询月末(查询时点上尚未收款) + lines = lines.filtered( + lambda l: ( + l.deposit_state in ('unpaid', 'no_paid') and l.due_date and l.due_date <= month_last + ) or ( + l.deposit_state == 'paid' and l.payout_date and l.payout_date > month_last + ) + ) + rows = [] total_amount = 0.0 for idx, rec in enumerate(lines, start=1): @@ -99,3 +120,37 @@ class DepositCumArrearsReport(models.Model): {'name': '合计欠收', 'amount': round(total_amount, 2)}, ] return {"rows": rows, "stats": stats} + + @api.model + def get_receivable_filter_domains(self, params): + """押金累计欠收报表:返回物业/承租方/合同的候选 ID 集合。""" + domain = [ + ('management_type_id.name', '=', '押金'), + ('is_invalid', '!=', True), + ] + + 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 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) + + property_ids = set(receivables.mapped('property_ids').ids) + lessee_ids = set(receivables.mapped('lessee_id').ids) + contract_ids = set(receivables.mapped('contract_id').ids) + + return { + 'property_ids': list(property_ids), + 'lessee_ids': list(lessee_ids), + 'contract_ids': list(contract_ids), + } diff --git a/yuthon_report/models/deposit_month_received_report.py b/yuthon_report/models/deposit_month_received_report.py index 22365ae12..1428a256d 100644 --- a/yuthon_report/models/deposit_month_received_report.py +++ b/yuthon_report/models/deposit_month_received_report.py @@ -13,10 +13,13 @@ class DepositMonthReceivedReport(models.Model): 押金本月实收报表: - 数据源:property.accounts.receivable - 管理费用类型为"押金" - - 押金状态为"已收" - 非作废记录 - - 支付日期(payout_date)在查询月内 - 金额:original_amount - discount_amount + - 状态取数逻辑(放宽 domain + 内存过滤): + - 已收(paid):payout_date 存在且在查询月内(month_first <= payout_date <= month_last) + - 已退(yes):退款日期(has_date) > 查询月末 → 查询时还没退,应包含 + 退款日期(has_date) <= 查询月末 → 已退,不包含 + (已退状态不受 payout_date 约束) """ date_start = params.get("date_start") query_date = datetime.datetime.fromisoformat(date_start).date() if date_start else datetime.date.today() @@ -24,12 +27,11 @@ class DepositMonthReceivedReport(models.Model): last_day = calendar.monthrange(query_date.year, query_date.month)[1] month_last = query_date.replace(day=last_day) + # 放宽 domain,只做基础筛选 domain = [ ('management_type_id.name', '=', '押金'), - ('deposit_state', 'in', ['paid', 'no_paid']), ('is_invalid', '!=', True), - ('payout_date', '>=', month_first), - ('payout_date', '<=', month_last), + ('deposit_state', 'in', ['paid', 'yes']), ] keyword = params.get("keyword") @@ -43,15 +45,34 @@ class DepositMonthReceivedReport(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)) if partner_id: 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)) - # 使用 property.accounts.receivable 模型查询 - lines = self.env['property.accounts.receivable'].sudo().search(domain, order="contract_id asc") + lines = self.sudo().search(domain, order="contract_id asc") + + # 内存过滤:按状态分别处理 + # - 已收(paid):收款日期在查询月内(month_first <= payout_date <= month_last) + # - 已退(yes):退款日期 > 查询月末(查询时还没退,不受 payout_date 约束) + lines = lines.filtered( + lambda l: ( + l.deposit_state == 'paid' and l.payout_date and month_first <= l.payout_date <= month_last + ) or ( + l.deposit_state == 'yes' and l.has_date and l.has_date > month_last + ) + ) rows = [] total_amount = 0.0 @@ -101,3 +122,37 @@ class DepositMonthReceivedReport(models.Model): {'name': '合计金额', 'amount': round(total_amount, 2)}, ] return {"rows": rows, "stats": stats} + + @api.model + def get_receivable_filter_domains(self, params): + """押金本月实收报表:返回物业/承租方/合同的候选 ID 集合。""" + domain = [ + ('management_type_id.name', '=', '押金'), + ('is_invalid', '!=', True), + ] + + 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 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) + + property_ids = set(receivables.mapped('property_ids').ids) + lessee_ids = set(receivables.mapped('lessee_id').ids) + contract_ids = set(receivables.mapped('contract_id').ids) + + return { + 'property_ids': list(property_ids), + 'lessee_ids': list(lessee_ids), + 'contract_ids': list(contract_ids), + } diff --git a/yuthon_report/models/deposit_pre_received_report.py b/yuthon_report/models/deposit_pre_received_report.py index b3ca9f7e5..5ba33674e 100644 --- a/yuthon_report/models/deposit_pre_received_report.py +++ b/yuthon_report/models/deposit_pre_received_report.py @@ -16,7 +16,7 @@ class DepositPreReceivedReport(models.Model): - 非作废记录 - 金额:original_amount - discount_amount - 状态取数逻辑: - - 已收(paid):payout_date 存在且 <= 查询月末(含查询月当月) + - 已收(paid):payout_date 存在且 < 查询月初(前期实收 = 查询月之前收到,不含查询月) - 已退(yes):退款日期(has_date) > 查询月末 → 查询时还没退,应包含 退款日期(has_date) <= 查询月末 → 已退,不包含 (已退状态不受 payout_date 约束) @@ -64,11 +64,11 @@ class DepositPreReceivedReport(models.Model): lines = self.sudo().search(domain, order="contract_id asc") # 内存过滤:按状态分别处理 - # - 已收(paid):收款日期必须存在且 <= 查询月末(含查询月当月) + # - 已收(paid):收款日期必须存在且 < 查询月初(前期实收 = 查询月之前收到) # - 已退(yes):退款日期 > 查询月末(查询时还没退,不受 payout_date 约束) lines = lines.filtered( lambda l: ( - l.deposit_state == 'paid' and l.payout_date and l.payout_date <= month_last + l.deposit_state == 'paid' and l.payout_date and l.payout_date < month_first ) or ( l.deposit_state == 'yes' and l.has_date and l.has_date > month_last ) From ff86aeee5fb9e2e6772a4bd4559868e21c9baf39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Wed, 10 Jun 2026 11:45:37 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=8A=A5=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yuthon_property_approval/views/property_lease_contract.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/yuthon_property_approval/views/property_lease_contract.xml b/yuthon_property_approval/views/property_lease_contract.xml index ec1553983..6c17b8181 100644 --- a/yuthon_property_approval/views/property_lease_contract.xml +++ b/yuthon_property_approval/views/property_lease_contract.xml @@ -11,6 +11,7 @@ + From 031bd4c7e221a009db4abf8f3a0694a5d6cdc6d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= <9664676+pengyuthon@user.noreply.gitee.com> Date: Wed, 10 Jun 2026 12:07:21 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- soong_workflow/models/soong_workflow_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 37ebcccd2..644426afc 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -1634,7 +1634,7 @@ class SoongWorkflowMixin(models.AbstractModel): id_el = etree.Element("field") id_el.set("name", "log_ids") id_el.set("invisible", "1") - if self._name == "purchase.order": + if self._name in ["purchase.order", "property.management"]: # 原有流程节点状态只读 + 额外增加 state=purchase 也只读 field_inst.set("readonly", "(state in %s) or (state == 'purchase')" % readonly_arr) else: