添加功能

This commit is contained in:
李鹏宇
2025-09-05 11:48:48 +08:00
parent 149330324e
commit e59e065a24
12 changed files with 151 additions and 87 deletions
@@ -154,7 +154,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">soong.workflow.record</field>
<field name="view_mode">tree,kanban,search</field>
<field name="context">{'check_employee': 1}</field>
<field name="context">{'check_employee': 1, 'to_do': 1, 'approve_state':1 }</field>
<field name="domain">[('users_ids', 'in', uid), ('reclaim_state', '=', False)]</field>
<field name="search_view_id" ref="soong_workflow_record_search"/>
</record>
@@ -43,6 +43,7 @@ class HrAttendanceDetail(models.Model):
department_id = fields.Many2one('hr.department', string="部门", related="employee_id.department_id", readonly=True, store=True)
source = fields.Selection([('iot', '考勤机'), ('mini_programs', '小程序')], string="来源")
attendance_iot_id = fields.Many2one('attendance.iot', string="设备号")
attendance_address = fields.Char(related="attendance_iot_id.attendance_address", string="设备地址")
userid = fields.Char(string='userid')
groupname = fields.Char(string='打卡规则名称')
checkin_type = fields.Char(string='打卡类型')
@@ -33,7 +33,7 @@ class PropertyBankStatements(models.Model):
original_amount = fields.Float(string='交易金额')
yes_amount = fields.Float(string='已对')
no_amount = fields.Float(string='未对')
is_reconciliation = fields.Boolean('是否已对账')
reconciliation_time = fields.Datetime('对账时间')
voucher_type = fields.Selection([('electronic_transfer', '电子转账凭证'), ('telegraphic_transfer', '电汇凭证')], string='凭证种类')
remake = fields.Text('备注')
registered = fields.Float('挂账')
@@ -52,7 +52,7 @@ class PropertyBankStatements(models.Model):
'receivable_id',
string='修改应收单'
)
is_reconciliation = fields.Boolean('是否对账') # 无效
company_select = fields.Selection([('jhtz', '天河投资'), ('thwg', '天河物管'), ('thcj', '天河城建')])
property_ids = fields.Many2many('yuthon.property', string='物业地址')
bank_state = fields.Selection([('not_reconciled', '未对账'), ('reconciled', '已对账'), ('registered', '挂账'), ('other', '其他')], string='状态', default='not_reconciled')
@@ -183,3 +183,27 @@ class PropertyBankStatements(models.Model):
return record
def disposable(self):
bank_ids = self.env["property.bank.statements"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for rec in bank_ids:
penalty_type = self.env['yuthon.management.type'].search(
[('name', '=', '违约金')],
limit=1)
bank_lines = self.env['property.bank.line'].search([
('bank', '=', rec.name),
('tenant_id.name', '!=', False),
])
if bank_lines:
tenant_id = bank_lines[0].tenant_id.id
start_date = (rec.start_time + timedelta(hours=8)).date()
accounts = self.env['property.accounts.receivable'].search([
('payout_date', '=', start_date),
('lessee_id', '=', tenant_id),
('contract_id', 'in', rec.contract_ids.ids),
('property_id', 'in', rec.property_ids.ids),
('management_type_id', '!=', penalty_type.id),
])
if accounts:
rec.reconciliation_time = accounts[0].reconciliation_time
@@ -27,7 +27,6 @@
<field name="number" optional="hide"/>
<field name="bank_state"/>
<field name="voucher_type" optional="hide"/>
<field name="is_reconciliation" column_invisible="1"/>
</tree>
</field>
</record>
@@ -65,7 +64,6 @@
<field name="number" optional="hide"/>
<field name="bank_state"/>
<field name="voucher_type" optional="hide"/>
<field name="is_reconciliation" column_invisible="1"/>
<button name="other" type="object" string="其他" class="btn btn-primary"/>
</tree>
</field>
@@ -45,6 +45,12 @@ class PropertyBankStatements(models.Model):
contract_ids = fields.Many2many('property.lease.contract', string="租赁合同审批")
accounts_id = fields.Many2one('property.accounts.approval', string="关联生成应收审批单")
def batch_revocation(self):
bank_ids = self.env["property.bank.statements"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for rec in bank_ids:
rec.revocation()
def revocation(self):
for rec in self:
penalty_type = self.env['yuthon.management.type'].search(
@@ -55,69 +61,83 @@ class PropertyBankStatements(models.Model):
('bank', '=', rec.name),
('tenant_id.name', '!=', False),
])
if bank_lines:
tenant_id = bank_lines[0].tenant_id.id
rec.bank_state = 'not_reconciled'
rec.registered = 0
rec.no_amount = rec.original_amount
rec.yes_amount = 0
penalty_records = self.env['property.accounts.receivable'].search([('bank_id', '=', self.id)])
if not penalty_records:
start_date_obj = fields.Date.from_string(start_date)
year = start_date_obj.year
month = start_date_obj.month
month_start = datetime(year, month, 1).date()
if month == 12:
month_end = datetime(year, 12, 31).date()
else:
month_end = (datetime(year, month + 1, 1).date() - relativedelta(days=1))
month_start_str = fields.Date.to_string(month_start)
month_end_str = fields.Date.to_string(month_end)
penalty_records = self.env['property.accounts.receivable'].search([
('due_date', '>=', month_start_str),
('due_date', '<=', month_end_str),
('lessee_id', '=', tenant_id),
('contract_id', 'in', rec.contract_ids.ids),
('property_id', 'in', rec.property_ids.ids),
('management_type_id', '=', penalty_type.id)
])
to_restore = penalty_records.filtered(lambda r: r.is_write)
if to_restore:
to_restore.write({'is_write': False,
'due_date_end': None,
'delivered1': None,
'is_reconciliation': False,
'payout_date': None,
})
return
if not bank_lines:
information = self.env['property.tenant.information'].search(
[('name', '=', rec.name_account)],
limit=1)
if information:
if information.bank_ids:
information.bank_ids.unlink()
information.bank_ids.create({
'tenant_id': information.id,
'bank': rec.name,
'user': information.name,
'name': information.name
})
target_year = start_date.year
target_month = start_date.month
to_delete = penalty_records.filtered(
lambda r: not r.is_write
and fields.Date.from_string(r.due_date).year == target_year
and fields.Date.from_string(r.due_date).month == target_month
)
if to_delete:
to_delete.unlink()
tenant_id = bank_lines[0].tenant_id.id
rec.bank_state = 'not_reconciled'
rec.registered = 0
rec.no_amount = rec.original_amount
rec.yes_amount = 0
rec.reconciliation_time = None
accounts = self.env['property.accounts.receivable'].search([
('payout_date', '=', start_date),
penalty_records = self.env['property.accounts.receivable'].search([('bank_id', '=', self.id)])
if not penalty_records:
start_date_obj = fields.Date.from_string(start_date)
year = start_date_obj.year
month = start_date_obj.month
month_start = datetime(year, month, 1).date()
if month == 12:
month_end = datetime(year, 12, 31).date()
else:
month_end = (datetime(year, month + 1, 1).date() - relativedelta(days=1))
month_start_str = fields.Date.to_string(month_start)
month_end_str = fields.Date.to_string(month_end)
penalty_records = self.env['property.accounts.receivable'].search([
('due_date', '>=', month_start_str),
('due_date', '<=', month_end_str),
('lessee_id', '=', tenant_id),
('contract_id', 'in', rec.contract_ids.ids),
('property_id', 'in', rec.property_ids.ids),
('management_type_id', '!=', penalty_type.id),
('management_type_id', '=', penalty_type.id)
])
if accounts:
for account in accounts:
account.write({'is_reconciliation': False,
'payout_date': False,
'delivered1': 0,
'reconciliation_time': False,
'remark': None,
})
else:
raise UserError(f'未找到银行账号为{rec.name}的承租方,请根据承租方姓名在承租方管理里面配置')
to_restore = penalty_records.filtered(lambda r: r.is_write)
if to_restore:
to_restore.write({'is_write': False,
'due_date_end': None,
'delivered1': None,
'is_reconciliation': False,
'payout_date': None,
})
return
target_year = start_date.year
target_month = start_date.month
to_delete = penalty_records.filtered(
lambda r: not r.is_write
and fields.Date.from_string(r.due_date).year == target_year
and fields.Date.from_string(r.due_date).month == target_month
)
if to_delete:
to_delete.unlink()
accounts = self.env['property.accounts.receivable'].search([
('payout_date', '=', start_date),
('lessee_id', '=', tenant_id),
('contract_id', 'in', rec.contract_ids.ids),
('property_id', 'in', rec.property_ids.ids),
('original_amount', '=', rec.original_amount),
('management_type_id', '!=', penalty_type.id),
])
if accounts:
for account in accounts:
account.write({'is_reconciliation': False,
'payout_date': False,
'delivered1': 0,
'reconciliation_time': False,
'remark': None,
})
def binding_information(self):
return {
@@ -153,18 +173,6 @@ class PropertyBankStatements(models.Model):
statement.contract_ids = [(5,)]
statement.property_ids = [(5,)]
def button_bank_state(self):
receivable_ids = self.env["property.bank.statements"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for record in receivable_ids:
record.bank_state = 'reconciled'
def button_state(self):
receivable_ids = self.env["property.bank.statements"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for record in receivable_ids:
record.bank_state = 'not_reconciled'
def contract_penalty(self):
statements_ids = self.env['property.bank.statements'].search([('is_put', '=', True)])
for record in statements_ids:
@@ -515,7 +515,7 @@
<field name="contract_ids" string="合同编号" widget="many2many_tags" readonly="1"/>
</xpath>
<xpath expr="//field[@name='start_time']" position="before">
<button name="button_reconciliation" type="object" string="对账" class="btn btn-primary" invisible="is_reconciliation"/>
<button name="button_reconciliation" type="object" string="对账" class="btn btn-primary" invisible="bank_state != 'not_reconciled'"/>
<button name="binding_information" type="object" string="绑定信息" class="btn btn-primary"/>
</xpath>
</field>
@@ -525,25 +525,18 @@
<field name="model">property.bank.statements</field>
<field name="inherit_id" ref="yuthon_property.view_property_bank_statements_tree1"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='is_reconciliation']" position="after">
<xpath expr="//field[@name='start_time']" position="after">
<field name="registered" optional="hide"/>
<button name="revocation" type="object" class="btn btn-primary" string="撤销" invisible="bank_state == 'not_reconciled'"/>
</xpath>
</field>
</record>
<record id="all_button_bank_state" model="ir.actions.server">
<field name="name">初始化状态</field>
<record id="all_batch_revocation" model="ir.actions.server">
<field name="name">批量撤销</field>
<field name="model_id" ref="yuthon_property.model_property_bank_statements"/>
<field name="binding_model_id" ref="yuthon_property.model_property_bank_statements"/>
<field name="state">code</field>
<field name="code">action = model.button_bank_state()</field>
</record>
<record id="button_state" model="ir.actions.server">
<field name="name">恢复</field>
<field name="model_id" ref="yuthon_property.model_property_bank_statements"/>
<field name="binding_model_id" ref="yuthon_property.model_property_bank_statements"/>
<field name="state">code</field>
<field name="code">action = model.button_state()</field>
<field name="code">action = model.batch_revocation()</field>
</record>
<!-- 违约金 -->
<record id="inherit_view_property_penalty_list_tree" model="ir.ui.view">
@@ -14,17 +14,34 @@ class ClickReconciliationWizard(models.Model):
])
# 直接查询符合条件的对账单
for receivable in receivable_ids:
due_date = receivable.due_date
month_start = datetime.combine(due_date.replace(day=1), datetime.min.time())
if due_date.month == 12:
month_end = datetime.combine(
datetime(due_date.year + 1, 1, 1),
datetime.min.time()
)
else:
month_end = datetime.combine(
datetime(due_date.year, due_date.month + 1, 1),
datetime.min.time()
)
statements_ids = self.env["property.bank.statements"].search([
('bank_state', 'in', ['not_reconciled', 'registered']),
('name_account', '=', receivable.lessee_id.name),
('start_time', '>=', month_start),
('start_time', '<', month_end),
('is_company', '=', True),
('contract_ids', 'in', receivable.contract_id.id),
('original_amount', '=', receivable.original_amount)
], order='start_time asc')
if statements_ids:
record = statements_ids[0]
record.yes_amount = receivable.original_amount
record.bank_state = 'reconciled'
record.reconciliation_time = fields.Datetime.now() - timedelta(hours=8)
record.no_amount = 0
receivable.write({
'is_reconciliation': True,
@@ -274,7 +274,7 @@ class PropertyReconciliationWizard(models.Model):
else:
rec.bank_id.registered = 0
rec.bank_id.bank_state = 'reconciled'
rec.reconciliation_time = fields.Datetime.now() - timedelta(hours=8),
first_line = bank_lines[0]
for line in rec.reconciliation_line_ids:
# 跳过金额为0的行
+1
View File
@@ -9,6 +9,7 @@
'depends': ['base', 'soong_workflow', 'hr', 'product', 'documents', 'purchase'],
'data': [
'security/ir.model.access.csv',
'security/company_rule.xml',
'views/inherit_product_product_views.xml',
'views/inherit_purchase_order_views.xml',
'views/purchase_workflow_views.xml',
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record model="ir.rule" id="purchase_order_rule">
<field name="name">采购多公司</field>
<field name="model_id" ref="model_purchase_order"/>
<field name="domain_force">[('company_id', 'in', company_ids)]</field>
</record>
</odoo>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record model="ir.rule" id="stock_picking_rule">
<field name="name">采购多公司</field>
<field name="model_id" ref="model_stock_picking"/>
<field name="domain_force">[('company_id', 'in', company_ids)]</field>
</record>
</odoo>
@@ -15,6 +15,12 @@
<xpath expr="//field[@name='picking_properties']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//page[@name='extra']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//page[@name='note']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='user_id']" position="attributes">
<attribute name="string">采购人员</attribute>
</xpath>