diff --git a/attendance_iot/controllers/kaoqin_test.py b/attendance_iot/controllers/kaoqin_test.py
index abfa562cc..ad39fbfb2 100644
--- a/attendance_iot/controllers/kaoqin_test.py
+++ b/attendance_iot/controllers/kaoqin_test.py
@@ -40,6 +40,7 @@ class BusController(Controller):
)
if not exist:
employee.write({
+ 'avatar_image': data.get('photo'),
'image_1920': data.get('photo'),
'attendance_iot_ids': [(0, 0, {
'employee_id': employee.id,
@@ -47,6 +48,7 @@ class BusController(Controller):
'attendance_address': ''
})]
})
+ _logger.info(f"-------------{employee.name}人脸更新触发------人脸数据{data.get('photo')}-------------")
_logger.info("-------------------------%s创建成功-------------------------------" % (employee.name))
return {"Result": 0, "Msg": "添加成功"}
diff --git a/yuthon_issue/views/issue_library_views.xml b/yuthon_issue/views/issue_library_views.xml
index b60e4f858..d77ac0eb5 100644
--- a/yuthon_issue/views/issue_library_views.xml
+++ b/yuthon_issue/views/issue_library_views.xml
@@ -21,10 +21,10 @@
-
-
-
-
+
+
+
+
@@ -391,16 +391,17 @@
-
+
+
-
-
-
+
+
+
@@ -435,16 +436,17 @@
-
+
+
-
-
-
+
+
+
@@ -586,7 +588,7 @@
['draft', 'to_draft'])]
- {'from_action': 'issue_library_action3', 'search_default_to_approval': 1}
+ {'from_action': 'issue_library_action3'}
@@ -599,7 +601,7 @@
[('is_push_party', '=', True),('issue_state', 'not in', ['draft', 'to_draft']),
('is_push_depart', '=', True), ('company_id.name', '!=', '集团本部')]
- {'from_action': 'issue_library_action3', 'search_default_to_approval': 1}
+ {'from_action': 'issue_library_action8'}
- {'from_action': 'issue_library_action4', 'search_default_to_approval': 1}
+ {'from_action': 'issue_library_action4'}
@@ -933,7 +935,7 @@
('is_push_depart', '=', True)]
- {'from_action': 'issue_library_action5', 'search_default_to_approval': 1}
+ {'from_action': 'issue_library_action5'}
diff --git a/yuthon_property_approval/models/property_bills_payable.py b/yuthon_property_approval/models/property_bills_payable.py
index 97dbea493..49c4c642c 100644
--- a/yuthon_property_approval/models/property_bills_payable.py
+++ b/yuthon_property_approval/models/property_bills_payable.py
@@ -28,6 +28,13 @@ class PropertyBillsPayable(models.Model):
document_ids = fields.Many2many('ir.attachment', string="附件")
active = fields.Boolean('Active', default=True, tracking=True)
work_end = fields.Boolean(string="结束")
+ payment_type = fields.Selection([
+ ('deposit_refund', '退押'),
+ ('lease_refund', '退租'),
+ ('engineering', '工程款'),
+ ('agency_fee', '中介费'),
+ ('other', '其他')
+ ], string='付款类型')
def _get_default_name_title(self):
return self._description if self._description else self._name
diff --git a/yuthon_property_approval/views/property_bills_payable_views.xml b/yuthon_property_approval/views/property_bills_payable_views.xml
index 45f1367c8..d2cfa7c5d 100644
--- a/yuthon_property_approval/views/property_bills_payable_views.xml
+++ b/yuthon_property_approval/views/property_bills_payable_views.xml
@@ -56,6 +56,7 @@
+
diff --git a/yuthon_property_approval/views/property_lease_contract.xml b/yuthon_property_approval/views/property_lease_contract.xml
index d5f5f5e1e..8bbb944ec 100644
--- a/yuthon_property_approval/views/property_lease_contract.xml
+++ b/yuthon_property_approval/views/property_lease_contract.xml
@@ -958,18 +958,20 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/yuthon_purchase/models/inherit_purchase_order.py b/yuthon_purchase/models/inherit_purchase_order.py
index eb0c2217f..bb7fa9cac 100644
--- a/yuthon_purchase/models/inherit_purchase_order.py
+++ b/yuthon_purchase/models/inherit_purchase_order.py
@@ -37,7 +37,7 @@ class InheritPurchaseOrder(models.Model):
default=lambda self: [(6, 0, [self.env.user.id])])
pay_way = fields.Selection([('onetime', '一次性'), ('installment', '分期')], string="付款方式", default='onetime')
reason_text = fields.Text(string="申请事由")
- purchase_type = fields.Selection([('fixed_asset', '固定资产采购'), ('sporadic', '零星采购'), ('comprehensive', '综合类')], string="采购类型", default='fixed_asset')
+ purchase_type = fields.Selection([('fixed_asset', '固定资产采购'), ('sporadic', '零星采购'), ('comprehensive', '综合类')], string="采购类型", default='comprehensive')
is_modify = fields.Boolean(string="可修改")
pay_line_ids = fields.One2many('purchase.order.pay.line', 'order_id', string="付款详情")
is_company = fields.Boolean(string="本公司", default=True, compute='_compute_is_company',search='_search_part_of_company')
diff --git a/yuthon_purchase/report/purchase_order_print_templates.xml b/yuthon_purchase/report/purchase_order_print_templates.xml
index 5e2f1b345..dfb0f564f 100644
--- a/yuthon_purchase/report/purchase_order_print_templates.xml
+++ b/yuthon_purchase/report/purchase_order_print_templates.xml
@@ -41,7 +41,7 @@
| 采购标的类型 |
- |
+ |
| 付款方式 |
diff --git a/yuthon_report/models/pre_arrears_report.py b/yuthon_report/models/pre_arrears_report.py
index d536b1d03..f8bb1f5e7 100644
--- a/yuthon_report/models/pre_arrears_report.py
+++ b/yuthon_report/models/pre_arrears_report.py
@@ -9,24 +9,30 @@ class PreArrearsReport(models.Model):
@api.model
def get_pre_arrears_report(self, params):
"""
- 前期欠收报表(数据源:receivable.modify.line):
- - 查询条件的日期对应应收账单的 due_date(应收日期在查询月内)
- - 收款日期(reconciliation_date)晚于应收日期(due_date)的记录就是欠收
- - 金额取收款记录的 not_collected(未收金额/欠收金额)
- - 按应收账单聚合,每张账单只出一行(汇总该账单下所有欠收收款金额)
+ 前期欠收报表(数据源:receivable.modify.line):
+ - 查询条件的日期对应应收账单的 due_date(应收日期在查询月及之前)
+ - 欠收条件:
+ - 收款日期在查询月之后(查询月时点还没收到钱)
+ - 或者 not_collected > 0 (部分收款,还没交完)
+ - 金额取值:
+ - 如果 not_collected > 0,取 not_collected (当前还欠的金额)
+ - 否则取 amount (已收金额)
+ - 按应收账单聚合,每张账单只出一行(汇总该账单下所有欠收收款金额)
"""
today = datetime.date.today()
this_month_first = today.replace(day=1)
date_start = params.get("date_start")
date_end = params.get("date_end")
- # 应收日期在查询日期之前(不含查询月)
- cutoff_date = datetime.datetime.fromisoformat(date_start).date() if date_start else this_month_first
+ # 应收日期在查询月及之前(包含查询月)
+ cutoff_date = datetime.datetime.fromisoformat(date_end).date() if date_end else this_month_first
+ # 查询月范围(用于判断收款是否在查询月内)
+ query_month_start = datetime.datetime.fromisoformat(date_start).date() if date_start else this_month_first
+ query_month_end = datetime.datetime.fromisoformat(date_end).date() if date_end else this_month_first
- # 核心逻辑:due_date < cutoff_date,且收款日期 > 应收日期
+ # 核心逻辑:due_date <= cutoff_date(查询月及之前的应收)
domain = [
- ('reconciliation_date', '!=', False),
- ('receivable_id.due_date', '<', cutoff_date),
+ ('receivable_id.due_date', '<=', cutoff_date),
('receivable_id.is_invalid', '=', False),
]
@@ -65,24 +71,43 @@ class PreArrearsReport(models.Model):
domain.append(('receivable_id.management_type_id.name', 'not in', ['押金', '违约金']))
lines = self.sudo().search(domain, order="receivable_id asc, reconciliation_date asc")
-
- # 欠收条件:reconciliation_date > due_date 且不在同一个月(跨月才算欠收)
+
+ # 欠收条件(同时满足):
+ # 1. reconciliation_date >= query_month_start (收款日期不能小于查询月)
+ # 2. 满足以下任一:
+ # a. reconciliation_date > query_month_end (收款日期在查询月之后,查询月时点还没收到钱)
+ # b. not_collected > 0 (部分收款,还没交完)
lines = lines.filtered(
- lambda l: l.reconciliation_date and l.receivable_id.due_date
- and l.reconciliation_date > l.receivable_id.due_date
- and not (
- l.reconciliation_date.year == l.receivable_id.due_date.year
- and l.reconciliation_date.month == l.receivable_id.due_date.month
- )
+ lambda l: l.reconciliation_date and l.reconciliation_date >= query_month_start and (
+ (l.reconciliation_date > query_month_end) or
+ (l.not_collected and l.not_collected > 0)
+ )
)
+
+ # 调试日志
+ print(f"[前期欠收报表] 查询到的 lines 数量: {len(lines)}")
+ for line in lines:
+ print(f" - line.id={line.id}, receivable_id={line.receivable_id.id}, "
+ f"due_date={line.receivable_id.due_date}, "
+ f"reconciliation_date={line.reconciliation_date}, "
+ f"not_collected={line.not_collected}, amount={line.amount}")
# 按应收账单聚合
rec_map = {}
for line in lines:
rid = line.receivable_id.id
if rid not in rec_map:
- rec_map[rid] = {'rec': line.receivable_id, 'amount': 0.0}
- rec_map[rid]['amount'] += line.not_collected or 0.0
+ rec_map[rid] = {'rec': line.receivable_id, 'amount': 0.0, 'reconciliation_dates': []}
+ # 金额取值:有未收金额取not_collected,否则取amount
+ rec_map[rid]['amount'] += (line.not_collected if (line.not_collected and line.not_collected > 0) else line.amount) or 0.0
+ # 收集收款日期
+ if line.reconciliation_date:
+ rec_map[rid]['reconciliation_dates'].append(line.reconciliation_date)
+
+ # 调试日志
+ print(f"[前期欠收报表] 聚合后的 rec_map 数量: {len(rec_map)}")
+ for rid, data in rec_map.items():
+ print(f" - receivable_id={rid}, amount={data['amount']}")
rows = []
total_amount = 0.0
@@ -103,6 +128,13 @@ class PreArrearsReport(models.Model):
}
elif rec:
property_val = rec.property_name or ''
+
+ # 应收开始日期
+ due_date_str = rec.due_date.strftime('%Y-%m-%d') if rec.due_date else ''
+
+ # 收款日期(取所有收款日期,用逗号分隔)
+ reconciliation_dates = data.get('reconciliation_dates', [])
+ reconciliation_date_str = ', '.join([d.strftime('%Y-%m-%d') for d in sorted(set(reconciliation_dates))]) if reconciliation_dates else ''
rows.append({
"序号": idx,
@@ -110,6 +142,7 @@ class PreArrearsReport(models.Model):
'model': 'property.lease.contract',
'id': contract.id,
'display_name': contract.contract_code,
+ 'view_id': self.env.ref('yuthon_property_approval.view_property_lease_contract_form1').id,
} if contract else "",
"物业名称": property_val,
"承租方名称": {
@@ -118,6 +151,8 @@ class PreArrearsReport(models.Model):
'display_name': rec.lessee_id.name,
} if rec.lessee_id else "",
"收款类型": rec.management_type_id.name if rec.management_type_id else "",
+ "应收开始日期": due_date_str,
+ "收款日期": reconciliation_date_str,
"金额": amount,
"所属公司": contract.lessor_id.name if contract and contract.lessor_id else "",
"管理员": {
diff --git a/yuthon_report/models/receivable_filter_domains.py b/yuthon_report/models/receivable_filter_domains.py
index c9b03eb94..f47f54e1d 100644
--- a/yuthon_report/models/receivable_filter_domains.py
+++ b/yuthon_report/models/receivable_filter_domains.py
@@ -8,48 +8,26 @@ class ReceivableModifyFilterDomains(models.Model):
@api.model
def get_receivable_filter_domains(self, params):
- """根据当前筛选条件,返回物业/承租方/合同的候选 ID 集合,用于三个下拉框互相过滤。"""
- # 注意:这里不按日期限制,只根据当前组合条件(公司/权属/片区/收款类型/物业/承租方/合同)
- # 来计算三类对象的全集,避免不同报表各自的日期口径导致候选集为空。
- domain = [
- ('receivable_id.is_invalid', '=', False),
- ]
+ """根据当前筛选条件,返回物业/承租方/合同的候选 ID 集合,用于三个下拉框互相过滤。
+
+ 注意:
+ - 候选集不应受收款类型、是否无效等业务条件过滤
+ - 只根据用户已选择的物业/承租方/合同进行互相过滤
+ - 具体的业务过滤由报表查询方法自己处理
+ """
+ domain = []
- keyword = params.get("keyword")
-
- if keyword:
- domain += [
- '|', '|',
- ('receivable_id.contract_id.contract_code', 'ilike', keyword),
- ('receivable_id.property_name', 'ilike', keyword),
- ('receivable_id.lessee_id.name', 'ilike', keyword),
- ]
-
- condition = params.get('condition')
- partner_id = params.get('partner_id')
- company_id = params.get('company_id')
- management_type_id = params.get('management_type_id')
+ # 只根据已选择的条件进行互相过滤,不应用业务过滤
property_id = params.get('property_id')
lessee_id = params.get('lessee_id')
contract_id = params.get('contract_id')
- if condition:
- domain.append(('receivable_id.tenure_type', '=', condition))
- if partner_id:
- domain.append(('receivable_id.precinct_id', '=', partner_id))
- if company_id:
- domain.append(('receivable_id.company_id', '=', company_id))
if property_id:
domain.append(('receivable_id.property_ids', 'in', [property_id]))
if lessee_id:
domain.append(('receivable_id.lessee_id', '=', lessee_id))
if contract_id:
domain.append(('receivable_id.contract_id', '=', contract_id))
- if management_type_id:
- domain.append(('receivable_id.management_type_id', '=', management_type_id))
- else:
- # 与各报表保持一致:默认剔除押金、违约金类型
- domain.append(('receivable_id.management_type_id.name', 'not in', ['押金', '违约金']))
lines = self.sudo().search(domain)
receivables = lines.mapped('receivable_id')
diff --git a/yuthon_report/static/src/components/yuthon_report/receivable_report.js b/yuthon_report/static/src/components/yuthon_report/receivable_report.js
index dc9e2dbc6..b4a5a42d8 100644
--- a/yuthon_report/static/src/components/yuthon_report/receivable_report.js
+++ b/yuthon_report/static/src/components/yuthon_report/receivable_report.js
@@ -216,7 +216,7 @@ class ReceivableReport extends Component {
type: 'ir.actions.act_window',
res_model: model,
res_id: id,
- views: [[false, 'form'], [false, 'search']],
+ views: [[view_id || false, 'form'], [false, 'search']],
target: 'new'
});
}
diff --git a/yuthon_report/views/pre_arrears_report.xml b/yuthon_report/views/pre_arrears_report.xml
index 9d95ac8da..9405e8149 100644
--- a/yuthon_report/views/pre_arrears_report.xml
+++ b/yuthon_report/views/pre_arrears_report.xml
@@ -13,11 +13,13 @@
"dateMode": "single",
"columns": [
{"headerName": "序号", "field": "序号", "width": 45, "flex": 0, "pinned": "left"},
+ {"headerName": "应收开始日期", "field": "应收开始日期", "flex": 1},
+ {"headerName": "收款日期", "field": "收款日期", "flex": 1},
+ {"headerName": "金额", "field": "金额", "flex": 1, "type": "number"},
{"headerName": "合同编号", "field": "合同编号", "flex": 1.2},
{"headerName": "物业名称", "field": "物业名称", "flex": 2.5},
{"headerName": "承租方名称", "field": "承租方名称", "flex": 1.4},
{"headerName": "收款类型", "field": "收款类型", "flex": 1},
- {"headerName": "金额", "field": "金额", "flex": 1, "type": "number"},
{"headerName": "所属公司", "field": "所属公司", "flex": 1},
{"headerName": "管理员", "field": "管理员", "flex": 1}
]
diff --git a/yuthon_will_task/controllers/main.py b/yuthon_will_task/controllers/main.py
index 33c7d3c34..a120d47c4 100644
--- a/yuthon_will_task/controllers/main.py
+++ b/yuthon_will_task/controllers/main.py
@@ -121,6 +121,7 @@ class YuthonWillTask(http.Controller):
'employee_num': ','.join(task.employee_ids.mapped('name')) if task.employee_ids else '',
'start_date': fields.Date.to_string(task.start_date),
'weekday': weekday_str,
+ 'address': task.address or '',
'request_hour_from': '',
'request_hour_to': '',
'state': task.task_state,
diff --git a/yuthon_work_brand/views/hr_menus.xml b/yuthon_work_brand/views/hr_menus.xml
index b856ffa6c..3d03ca568 100644
--- a/yuthon_work_brand/views/hr_menus.xml
+++ b/yuthon_work_brand/views/hr_menus.xml
@@ -308,11 +308,11 @@
parent="attendance_resources_setting_root_board"
sequence="8"
action="yuthon_hr_attendance.view_overtime_page_action"/>
-
+
+
+
+
+