This commit is contained in:
李鹏宇
2026-06-10 13:46:17 +08:00
5 changed files with 127 additions and 16 deletions
@@ -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:
@@ -11,6 +11,7 @@
<field name="employee_ids" widget="many2many_tags"/>
<field name="approve_state" string="审批状态" widget="badge" decoration-danger="approve_state == 'end'" decoration-success="approve_state == 'pending'"/>
<field name="version" string="版本"/>
<field name="is_modify" invisible="1"/>
</tree>
</field>
</record>
@@ -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),
}
@@ -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),
}
@@ -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
)