添加功能

This commit is contained in:
zhou
2025-06-23 22:26:30 +08:00
parent 447a5f6907
commit 66ccb31413
9 changed files with 187 additions and 76 deletions
@@ -9,11 +9,12 @@
<header>
<button name="all_red" string="红冲" type="object" class="btn btn-primary"/>
</header>
<field name="payout_date"/>
<field name="property_id"/>
<field name="lessee_id"/>
<field name="management_type_id"/>
<button name="receivable_log_wizard" string="日志" type="object" class="oe_highlight"/>
<field name="due_date"/>
<field name="payout_date"/>
<field name="lessee_id"/>
<field name="property_id"/>
<field name="management_type_id"/>
<field name="original_amount"/>
<field name="discount_amount"/>
<field name="delivered1"/>
@@ -31,10 +32,6 @@
<field name="difference_amount"/>
<field name="receivable_log" column_invisible="1"/>
<field name="is_suspend" optional="hide"/>
<button name="invalid" string="作废" type="object" class="oe_highlight"/>
<button name="suspend" string="激活" type="object" class="oe_highlight" invisible="not is_suspend"/>
<button name="unsuspend" string="挂起" type="object" class="oe_highlight" invisible="is_suspend"/>
<button name="receivable_log_wizard" string="日志" type="object" class="oe_highlight"/>
</tree>
</field>
</record>
+1
View File
@@ -75,6 +75,7 @@
'wizard/property_reconciliation_wizard_views.xml',
'wizard/property_management_wizard.xml',
'wizard/click_reconciliation_wizard_views.xml',
'wizard/accounts_wizard_views.xml',
'wizard/property_rental_wizard_views.xml',
'wizard/property_meeting_wizard_views.xml',
'views/property_menu_all.xml',
@@ -300,7 +300,8 @@ class PropertyAccountsReceivable(models.Model):
('start_time', '<=', end_date),
])
if statements:
receivable.payout_date = statements.start_time.date()
for statement in statements:
receivable.payout_date = statement.start_time.date()
else:
receivable.payout_date = receivable.due_date
@@ -348,43 +349,33 @@ class PropertyAccountsReceivable(models.Model):
penalty = days_difference * receivable.receivable_id.difference_amount
receivable.receivable_id.write({'penalty': penalty})
def receivable_return(self):
model_type_data = {
'水费': 'property.water.list',
'电费': 'property.tariff.list',
'押金': 'property.deposit.list',
'租金': 'property.rent.list'
}
for rec in self:
model_type = model_type_data.get(rec.management_type_id.name)
if model_type:
model_id = self.env[model_type].search([('contract_id', '=', rec.contract_id.id)])
if model_id:
model_id.write({'is_push': False})
# 银行流水对应的已对账改为未对账
due_year = rec.due_date.year
due_month = rec.due_date.month
import calendar
last_day = calendar.monthrange(due_year, due_month)[1]
# 构建日期范围条件(使用正确的最后一天)
start_date = f"{due_year}-{due_month:02d}-01"
end_date = f"{due_year}-{due_month:02d}-{last_day}"
# 搜索条件使用大于等于当月第一天,小于等于当月最后一天
statements = self.env['property.bank.statements'].search([
('name_account', '=', rec.lessee_id.name),
('bank_state', '=', 'reconciled'),
('start_time', '>=', start_date),
('start_time', '<=', end_date),
])
for statement in statements:
statement.write({'bank_state': 'not_reconciled'})
#删除原记录
rec.unlink()
# 批量撤销
def batch_receivable_return(self):
archives_ids = self.env["property.accounts.receivable"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for rec in archives_ids:
# 银行流水对应的已对账改为未对账
due_year = rec.due_date.year
due_month = rec.due_date.month
import calendar
last_day = calendar.monthrange(due_year, due_month)[1]
# 构建日期范围条件(使用正确的最后一天)
start_date = f"{due_year}-{due_month:02d}-01"
end_date = f"{due_year}-{due_month:02d}-{last_day}"
# 搜索条件使用大于等于当月第一天,小于等于当月最后一天
statements = self.env['property.bank.statements'].search([
('name_account', '=', rec.lessee_id.name),
('bank_state', '=', 'reconciled'),
('start_time', '>=', start_date),
('start_time', '<=', end_date),
])
rec.is_reconciliation = False
for statement in statements:
statement.write({'bank_state': 'not_reconciled'})
# 批量退回
def action_refuse_all(self):
model_type_data = {
'水费': 'property.water.list',
'电费': 'property.tariff.list',
@@ -399,27 +390,20 @@ class PropertyAccountsReceivable(models.Model):
model_id = self.env[model_type].search([('contract_id', '=', rec.contract_id.id)])
if model_id:
model_id.write({'is_push': False})
# 银行流水对应的已对账改为未对账
due_year = rec.due_date.year
due_month = rec.due_date.month
import calendar
last_day = calendar.monthrange(due_year, due_month)[1]
# 构建日期范围条件(使用正确的最后一天)
start_date = f"{due_year}-{due_month:02d}-01"
end_date = f"{due_year}-{due_month:02d}-{last_day}"
# 搜索条件使用大于等于当月第一天,小于等于当月最后一天
statements = self.env['property.bank.statements'].search([
('name_account', '=', rec.lessee_id.name),
('bank_state', '=', 'reconciled'),
('start_time', '>=', start_date),
('start_time', '<=', end_date),
])
for statement in statements:
statement.write({'bank_state': 'not_reconciled'})
rec.unlink()
def button_accounts_wizard(self):
return {
"type": "ir.actions.act_window",
"name": "操作弹窗",
"res_model": "accounts.wizard",
"view_mode": "form",
"target": "new",
"context": {
"default_accounts_id": self.id
}
}
# 租金
class PropertyRentList(models.Model):
@@ -98,4 +98,5 @@ access_property_management_line, property_management_line,model_property_managem
access_property_management_line2, property_management_line2,model_property_management_line2,base.group_user,1,1,1,1
access_property_management_wizard, property_management_wizard,model_property_management_wizard,base.group_user,1,1,1,1
access_click_reconciliation_wizard, click_reconciliation_wizard,model_click_reconciliation_wizard,base.group_user,1,1,1,1
access_accounts_wizard, accounts_wizard,model_accounts_wizard,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
98 access_property_management_wizard property_management_wizard model_property_management_wizard base.group_user 1 1 1 1
99 access_click_reconciliation_wizard click_reconciliation_wizard model_click_reconciliation_wizard base.group_user 1 1 1 1
100 access_accounts_wizard accounts_wizard model_accounts_wizard base.group_user 1 1 1 1
101
102
@@ -373,18 +373,20 @@
<field name="domain">[('is_push', '=', False)]</field>
</record>
<!--应收账单 -->
<record id="inherit_property_accounts_receivable_form" model="ir.ui.view">
<record id="inherit_property_accounts_receivable_form_tree" model="ir.ui.view">
<field name="name">property.accounts.receivable.tree</field>
<field name="model">property.accounts.receivable</field>
<field name="inherit_id" ref="yuthon_property.view_property_accounts_receivable_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='due_date']" position="before">
<button name="button_accounts_wizard" string="操作" type="object" class="btn btn-primary"/>
</xpath>
<xpath expr="//field[@name='property_id']" position="after">
<field name="contract_id" string="合同"/>
</xpath>
<xpath expr="//field[@name='receivable_log']" position="after">
<field name="penalty"/>
<field name="penalty_date"/>
<button name="receivable_return" string="撤销" class="btn-primary" type="object"/>
</xpath>
</field>
</record>
@@ -393,9 +395,9 @@
<field name="model">property.accounts.receivable</field>
<field name="arch" type="xml">
<search>
<field name="property_id"/>
<field name="lessee_id"/>
<field name="contract_id"/>
<field name="property_id"
string="综合搜索"
filter_domain="['|', '|', ('property_id.name', 'ilike', self), ('lessee_id.name', 'ilike', self), ('contract_id.contract_code', 'ilike', self)]"/>
<group expand="0" string="group_by">
<filter name="group_is_reconciliation" string="对账" context="{'group_by':'is_reconciliation'}"/>
<filter name="group_property_id" string="物业" context="{'group_by':'property_id'}"/>
@@ -562,12 +564,19 @@
<field name="code">action = model.all_penalty_date()</field>
</record>
<record id="all_button_return_property" model="ir.actions.server">
<field name="name">批量退回</field>
<field name="name">批量撤销</field>
<field name="model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="binding_model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="state">code</field>
<field name="code">action = model.batch_receivable_return()</field>
</record>
<record id="all_action_refuse_all" model="ir.actions.server">
<field name="name">批量退回</field>
<field name="model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="binding_model_id" ref="yuthon_property.model_property_accounts_receivable"/>
<field name="state">code</field>
<field name="code">action = model.action_refuse_all()</field>
</record>
<!--银行流水-->
<record id="inherit_property_bank_statements_tree" model="ir.ui.view">
<field name="name">property.bank.statements.tree</field>
+2 -1
View File
@@ -6,4 +6,5 @@ from . import property_physical_wizard
from . import property_reconciliation_wizard
from . import property_meeting_wizard
from . import property_management_wizard
from . import click_reconciliation_wizard
from . import click_reconciliation_wizard
from . import accounts_wizard
@@ -0,0 +1,86 @@
from odoo import models, fields, api, _, SUPERUSER_ID
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
class AccountsWizard(models.Model):
_name = 'accounts.wizard'
accounts_id = fields.Many2one('property.accounts.receivable', string='对账单')
def invalid(self):
receivable_log = (f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.accounts_id.property_id.name}的应收账单状态修改为作废')
for record in self.accounts_id:
original_log = record.receivable_log or ''
if original_log:
new_log = f"{original_log}\n{receivable_log}"
else:
new_log = receivable_log
return self.accounts_id.write({'is_invalid': True,
'receivable_log': new_log
})
# 激活
def suspend(self):
receivable_log = (
f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.accounts_id.property_id.name}的应收账单挂起')
for record in self.accounts_id:
original_log = record.receivable_log or ''
if original_log:
new_log = f"{original_log}\n{receivable_log}"
else:
new_log = receivable_log
return self.accounts_id.write({'is_suspend': False,'receivable_log': new_log})
# 挂起
def unsuspend(self):
receivable_log = (
f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.accounts_id.property_id.name}的应收账单取消挂起')
for record in self.accounts_id:
original_log = record.receivable_log or ''
if original_log:
new_log = f"{original_log}\n{receivable_log}"
else:
new_log = receivable_log
return self.accounts_id.write({'is_suspend': True,
'receivable_log':new_log
})
# 撤销
def receivable_return(self):
for rec in self.accounts_id:
# 银行流水对应的已对账改为未对账
due_year = rec.due_date.year
due_month = rec.due_date.month
import calendar
last_day = calendar.monthrange(due_year, due_month)[1]
# 构建日期范围条件(使用正确的最后一天)
start_date = f"{due_year}-{due_month:02d}-01"
end_date = f"{due_year}-{due_month:02d}-{last_day}"
# 搜索条件使用大于等于当月第一天,小于等于当月最后一天
statements = self.env['property.bank.statements'].search([
('name_account', '=', rec.lessee_id.name),
('bank_state', '=', 'reconciled'),
('start_time', '>=', start_date),
('start_time', '<=', end_date),
])
rec.is_reconciliation = False
for statement in statements:
statement.write({'bank_state': 'not_reconciled'})
# 退回
def action_refuse(self):
model_type_data = {
'水费': 'property.water.list',
'电费': 'property.tariff.list',
'押金': 'property.deposit.list',
'租金': 'property.rent.list'
}
for rec in self.accounts_id:
model_type = model_type_data.get(rec.management_type_id.name)
if model_type:
model_id = self.env[model_type].search([('contract_id', '=', rec.contract_id.id)])
if model_id:
model_id.write({'is_push': False})
rec.unlink()
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_accounts_wizard" model="ir.ui.view">
<field name="name">应收对账操作</field>
<field name="model">accounts.wizard</field>
<field name="arch" type="xml">
<form string="应收对账操作">
<group col="3">
<group>
<button name="invalid" type="object" string="作废" class="btn btn-primary button_width"/>
</group>
<group>
<button name="suspend" type="object" string="激活" class="btn btn-primary button_width"/>
</group>
<group>
<button name="unsuspend" type="object" string="挂起" class="btn btn-primary button_width"/>
</group>
<group>
<button name="receivable_return" type="object" string="撤销" class="btn btn-primary button_width"/>
</group>
<group>
<button name="action_refuse" type="object" string="退回" class="btn btn-primary button_width"/>
</group>
</group>
<footer/>
</form>
</field>
</record>
</odoo>
@@ -9,13 +9,16 @@ class ClickReconciliationWizard(models.Model):
message = fields.Text(string='确认信息', readonly=True)
def action_confirm(self):
statements_ids = self.env["property.bank.statements"].search([('bank_state', '=', 'not_reconciled')])
contracts = self.env["property.accounts.receivable"].search([
('is_reconciliation', '=', False)
unreconciled_contract_ids = self.env["property.accounts.receivable"].search([
('is_reconciliation', '=', False),
]).mapped('contract_id')
# 直接查询符合条件的对账单
statements_ids = self.env["property.bank.statements"].search([
('bank_state', '=', 'not_reconciled'),
('contract_ids', 'in', unreconciled_contract_ids.ids if unreconciled_contract_ids else [])
])
contract_ids = contracts.mapped('contract_id')
# 只处理合同ID存在于应收账款合同中的对账单记录
for record in statements_ids.filtered(lambda r: r.contract_id in contract_ids):
for record in statements_ids:
all_vals, total_rent_month = record._get_reconciliation_vals(record)
# 更新对账状态
if total_rent_month == record.original_amount: