!9290 Merge branch 'dev' of <a href="https://gitee.com/jinan-pengyusen-data/gzth">https://gitee.com/jinan-pengyusen-data/gzth</a> into dev_wang
Merge pull request !9290 from 李鹏宇/dev_wang
This commit is contained in:
@@ -286,27 +286,6 @@ class YuthonCatering(models.Model):
|
||||
'lunch': True,
|
||||
})
|
||||
|
||||
def fill_today_missing_catering(self):
|
||||
"""生成今天缺失员工的餐饮收集任务数据"""
|
||||
today = fields.Date.today()
|
||||
conf = self.env['yuthon.catering.conf'].search([], limit=1)
|
||||
if not conf or not conf.employee_ids:
|
||||
return
|
||||
create_vals = []
|
||||
for employee in conf.employee_ids:
|
||||
existing = self.search([
|
||||
('employee_id', '=', employee.id),
|
||||
('date', '=', today),
|
||||
], limit=1)
|
||||
if not existing:
|
||||
create_vals.append({
|
||||
'date': today,
|
||||
'employee_id': employee.id,
|
||||
'state': 'unconfirmed',
|
||||
})
|
||||
if create_vals:
|
||||
self.create(create_vals)
|
||||
|
||||
def batch_generate_catering(self):
|
||||
"""批量生成2025-12、2026-01、2026-02的餐饮收集任务数据,排除节假日"""
|
||||
from datetime import date as date_cls
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
<button name="task_catering22" string="一次修复" type="object" class="btn btn-primary"/>
|
||||
<button name="batch_confirm_catering" string="批量确认" type="object" class="btn btn-primary"/>
|
||||
<button name="batch_generate_catering" string="批量生成12/1/2月餐饮数据" type="object" class="btn btn-primary"/>
|
||||
<button name="fill_today_missing_catering" string="补生今日缺失数据" type="object" class="btn btn-primary"/>
|
||||
</header>
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
|
||||
@@ -6,6 +6,37 @@ from odoo import fields, models, api
|
||||
class YuthonProperty(models.Model):
|
||||
_inherit = 'property.accounts.receivable'
|
||||
|
||||
# 固定费用类型列(用于报表横向展示)
|
||||
FEE_COLUMNS = ['租金', '管理费', '水费', '电费', '违约金', '其他费用']
|
||||
|
||||
def _get_tax_rate_display(self, rec):
|
||||
"""从合同获取税率显示字符串"""
|
||||
try:
|
||||
tr = rec.contract_id.tax_rate.name if rec.contract_id and rec.contract_id.tax_rate else None
|
||||
if tr and str(tr).replace('%', '').strip():
|
||||
v = float(str(tr).replace('%', '').strip())
|
||||
return f"{v:.1f}%"
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
return "0.0%"
|
||||
|
||||
def _classify_fee_type(self, type_name):
|
||||
"""将应收类型归类到固定列"""
|
||||
if not type_name:
|
||||
return '其他费用'
|
||||
if '租' in type_name:
|
||||
return '租金'
|
||||
elif '管理' in type_name or '管' in type_name:
|
||||
return '管理费'
|
||||
elif '水' in type_name:
|
||||
return '水费'
|
||||
elif '电' in type_name:
|
||||
return '电费'
|
||||
elif '违约' in type_name:
|
||||
return '违约金'
|
||||
else:
|
||||
return '其他费用'
|
||||
|
||||
@api.model
|
||||
def get_complete_ledger_report(self, params):
|
||||
domain = []
|
||||
@@ -25,75 +56,82 @@ class YuthonProperty(models.Model):
|
||||
date_end = datetime.datetime.fromisoformat(params.get("date_end")).date()
|
||||
domain.append(("due_date", "<=", date_end))
|
||||
|
||||
# condition, 这里需要放到具体的搜索条件中 domain .
|
||||
condition = params.get('condition', False)
|
||||
partner_id = params.get('partner_id', False)
|
||||
company_id = params.get('company_id', False)
|
||||
|
||||
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))
|
||||
|
||||
receivables = self.search(domain)
|
||||
management_type_map = dict(
|
||||
self.env['yuthon.management.type'].search([]).mapped(lambda r: (r.id, r.name))
|
||||
)
|
||||
invoice_type_map = dict(
|
||||
self._fields['invoice_type']._description_selection(self.env)
|
||||
)
|
||||
|
||||
receivables = self.search(domain, order="contract_id asc, due_date asc")
|
||||
|
||||
# 按合同分组
|
||||
contract_map = {}
|
||||
for rec in receivables:
|
||||
cid = rec.contract_id.id if rec.contract_id else 0
|
||||
if cid not in contract_map:
|
||||
contract_map[cid] = {
|
||||
'recs': [],
|
||||
'info_rec': rec, # 取第一条记录作为基础信息
|
||||
}
|
||||
contract_map[cid]['recs'].append(rec)
|
||||
|
||||
rows = []
|
||||
type_totals = {}
|
||||
total_amount = 0.0
|
||||
|
||||
for idx, rec in enumerate(receivables, start=1):
|
||||
mgmt_type = management_type_map.get(rec.management_type_id.id, "") if rec.management_type_id else "未分类"
|
||||
amount = rec.original_amount or 0.0
|
||||
total_amount += amount
|
||||
|
||||
if mgmt_type not in type_totals:
|
||||
type_totals[mgmt_type] = {'amount': 0.0}
|
||||
type_totals[mgmt_type]['amount'] += amount
|
||||
|
||||
rows.append({
|
||||
total_fees = {col: 0.0 for col in self.FEE_COLUMNS}
|
||||
total_subtotal = 0.0
|
||||
idx = 1
|
||||
|
||||
for cid, data in contract_map.items():
|
||||
info_rec = data['info_rec']
|
||||
fee_row = {col: 0.0 for col in self.FEE_COLUMNS}
|
||||
|
||||
# 归类费用
|
||||
for rec in data['recs']:
|
||||
type_name = rec.management_type_id.name if rec.management_type_id else ''
|
||||
col = self._classify_fee_type(type_name)
|
||||
fee_row[col] += rec.original_amount or 0.0
|
||||
|
||||
subtotal = sum(fee_row.values())
|
||||
for col in self.FEE_COLUMNS:
|
||||
total_fees[col] += fee_row[col]
|
||||
total_subtotal += subtotal
|
||||
|
||||
row = {
|
||||
"序号": idx,
|
||||
"应收类型": mgmt_type,
|
||||
"应收开始": rec.due_date.strftime("%Y-%m-%d") if rec.due_date else "",
|
||||
"应收结束": rec.due_date_end.strftime("%Y-%m-%d") if rec.due_date_end else "",
|
||||
"当期金额": round(amount, 2),
|
||||
"应收开始": info_rec.due_date.strftime("%Y-%m-%d") if info_rec.due_date else "",
|
||||
"应收结束": info_rec.due_date_end.strftime("%Y-%m-%d") if info_rec.due_date_end else "",
|
||||
"合同编号": {
|
||||
'model': 'property.lease.contract',
|
||||
'id': rec.contract_id.id,
|
||||
'display_name': rec.contract_id.contract_code,
|
||||
} if rec.contract_id else "",
|
||||
'id': info_rec.contract_id.id,
|
||||
'display_name': info_rec.contract_id.contract_code,
|
||||
} if info_rec.contract_id else "",
|
||||
"承租方": {
|
||||
'model': 'property.tenant.information',
|
||||
'id': rec.lessee_id.id,
|
||||
'display_name': rec.lessee_id.name,
|
||||
} if rec.lessee_id else "",
|
||||
"物业名称": rec.property_name or "",
|
||||
"产权证号": rec.title_deed or "",
|
||||
"发票类型": rec.lessee_id.invoicing_ids[0].invoicing_type_id.name if rec.lessee_id and rec.lessee_id.invoicing_ids else "",
|
||||
"税率": (
|
||||
lambda tr: (
|
||||
lambda v: f"{v:.1f}%" if v is not None else "0.0%"
|
||||
)(
|
||||
float(str(tr).replace('%', '').strip())
|
||||
if tr and str(tr).replace('%', '').strip()
|
||||
else None
|
||||
)
|
||||
)(rec.contract_id.tax_rate.name if rec.contract_id and rec.contract_id.tax_rate else None)
|
||||
})
|
||||
|
||||
'id': info_rec.lessee_id.id,
|
||||
'display_name': info_rec.lessee_id.name,
|
||||
} if info_rec.lessee_id else "",
|
||||
"物业名称": info_rec.property_name or "",
|
||||
"产权证号": info_rec.title_deed or "",
|
||||
"发票类型": info_rec.lessee_id.invoicing_ids[0].invoicing_type_id.name if info_rec.lessee_id and info_rec.lessee_id.invoicing_ids else "",
|
||||
"税率": self._get_tax_rate_display(info_rec),
|
||||
}
|
||||
# 加入各费用列
|
||||
for col in self.FEE_COLUMNS:
|
||||
row[col] = round(fee_row[col], 2) if fee_row[col] else ""
|
||||
row["小计"] = round(subtotal, 2)
|
||||
rows.append(row)
|
||||
idx += 1
|
||||
|
||||
# 合计行
|
||||
summary_stats = []
|
||||
for type_name in sorted(type_totals.keys()):
|
||||
summary_stats.append({'name': type_name, 'amount': round(type_totals[type_name]['amount'], 2)})
|
||||
summary_stats.append({'name': '总合计', 'amount': round(total_amount, 2)})
|
||||
|
||||
for col in self.FEE_COLUMNS:
|
||||
summary_stats.append({'name': col, 'amount': round(total_fees[col], 2)})
|
||||
summary_stats.append({'name': '小计合计', 'amount': round(total_subtotal, 2)})
|
||||
|
||||
return {"rows": rows, "stats": summary_stats}
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -11,16 +11,21 @@
|
||||
"model": "property.accounts.receivable",
|
||||
"method": "get_complete_ledger_report",
|
||||
"columns": [
|
||||
{"headerName": "应收类型", "field": "应收类型", "flex": 1},
|
||||
{"headerName": "应收开始", "field": "应收开始", "flex": 1},
|
||||
{"headerName": "应收结束", "field": "应收结束", "flex": 1},
|
||||
{"headerName": "当期金额", "field": "当期金额", "flex": 1, "type": "number"},
|
||||
{"headerName": "合同编号", "field": "合同编号", "flex": 1},
|
||||
{"headerName": "承租方", "field": "承租方", "flex": 1},
|
||||
{"headerName": "物业名称", "field": "物业名称", "flex": 1},
|
||||
{"headerName": "物业名称", "field": "物业名称", "flex": 2},
|
||||
{"headerName": "产权证号", "field": "产权证号", "flex": 1},
|
||||
{"headerName": "发票类型", "field": "发票类型", "flex": 1},
|
||||
{"headerName": "税率", "field": "税率", "flex": 1}
|
||||
{"headerName": "税率", "field": "税率", "flex": 1},
|
||||
{"headerName": "租金", "field": "租金", "flex": 1, "type": "number"},
|
||||
{"headerName": "管理费", "field": "管理费", "flex": 1, "type": "number"},
|
||||
{"headerName": "水费", "field": "水费", "flex": 1, "type": "number"},
|
||||
{"headerName": "电费", "field": "电费", "flex": 1, "type": "number"},
|
||||
{"headerName": "违约金", "field": "违约金", "flex": 1, "type": "number"},
|
||||
{"headerName": "其他费用", "field": "其他费用", "flex": 1, "type": "number"},
|
||||
{"headerName": "小计", "field": "小计", "flex": 1, "type": "number"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user