diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py index 614932c94..e80c67ee9 100644 --- a/soong_workflow/models/soong_workflow_mixin.py +++ b/soong_workflow/models/soong_workflow_mixin.py @@ -891,6 +891,8 @@ class SoongWorkflowMixin(models.AbstractModel): and field_attrs.name.name == field_inst.attrib["name"] ): flag_show = True + if field_attrs.name.name in ["code", "name_title"]: + readonly_arr.append(node.node_name) if field_attrs.readonly: readonly_arr.append(node.node_name) if field_attrs.required: diff --git a/yuthon_property/__manifest__.py b/yuthon_property/__manifest__.py index 13ad74495..3a10d52ad 100644 --- a/yuthon_property/__manifest__.py +++ b/yuthon_property/__manifest__.py @@ -60,6 +60,7 @@ 'wizard/property_tenant_wizard_views.xml', 'wizard/evaluation_plan_wizard_views.xml', 'wizard/property_water_wizard_views.xml', + 'wizard/receivable_log_wizard_views.xml', 'wizard/property_statements_wizard_views.xml', 'views/menuitem.xml', ], diff --git a/yuthon_property/models/property_accounts_receivable.py b/yuthon_property/models/property_accounts_receivable.py index 729c9f5c8..9e35359e3 100644 --- a/yuthon_property/models/property_accounts_receivable.py +++ b/yuthon_property/models/property_accounts_receivable.py @@ -33,21 +33,86 @@ class PropertyAccountsReceivable(models.Model): is_billing = fields.Boolean(string='开票') is_reconciliation = fields.Boolean(string='对账') difference_amount = fields.Float(string='差额') + delivered1 = fields.Float(string='已交') + delivered = fields.Boolean() submitted = fields.Float(string='未交') is_invalid = fields.Boolean(string='作废') is_red = fields.Boolean(string='红冲') + red_state_date = fields.Date(string='红冲时间') is_push = fields.Boolean(string='已推送') management_type_id = fields.Many2one('yuthon.management.type', string='应收类型') last_update_time = fields.Datetime(string='最后修改时间') + receivable_log = fields.Text(string='应收日志') - def unlink(self): - return super().unlink() + @api.onchange('original_amount', 'delivered1') + def _get_submitted(self): + for record in self: + record.submitted = record.original_amount - record.delivered1 + + def invalid(self): + receivable_log = (f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name}的应收账单状态修改为作废') + for record in self: + original_log = record.receivable_log or '' + if original_log: + new_log = f"{original_log}\n{receivable_log}" + else: + new_log = receivable_log + return self.write({'is_invalid': True, + 'receivable_log': new_log + }) # 激活 def suspend(self): - return self.write({'is_suspend': False}) - + receivable_log = ( + f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name}的应收账单挂起') + for record in self: + original_log = record.receivable_log or '' + if original_log: + new_log = f"{original_log}\n{receivable_log}" + else: + new_log = receivable_log + return self.write({'is_suspend': False,'receivable_log': new_log}) # 挂起 def unsuspend(self): - return self.write({'is_suspend': True}) \ No newline at end of file + receivable_log = ( + f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name}的应收账单取消挂起') + for record in self: + original_log = record.receivable_log or '' + if original_log: + new_log = f"{original_log}\n{receivable_log}" + else: + new_log = receivable_log + return self.write({'is_suspend': True, + 'receivable_log':new_log + }) + + # 红冲 + def all_red(self): + receivable_ids = self.env["property.accounts.receivable"].browse( + self._context.get('active_ids', self._context.get('active_id'))) + property_list = [] + for receivable in receivable_ids: + property_list.append(receivable.property_id.id) + property_names = ",".join(property_list) + receivable_log = (f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {property_names}的应收账单红冲') + for record in self: + original_log = record.receivable_log or '' + if original_log: + new_log = f"{original_log}\n{receivable_log}" + else: + new_log = receivable_log + receivable.write({'is_red': True, 'red_state_date': fields.Date.today(), 'receivable_log': new_log}) + + + def receivable_log_wizard(self): + return { + 'name': '应收日志', + 'type': 'ir.actions.act_window', + 'res_model': 'receivable.log.wizard', + 'view_mode': 'form', + 'target': 'new', + 'context': { + 'default_name' : self.receivable_log + } + } diff --git a/yuthon_property/models/property_bank_statements.py b/yuthon_property/models/property_bank_statements.py index 8412c4408..8c8a3d4ad 100644 --- a/yuthon_property/models/property_bank_statements.py +++ b/yuthon_property/models/property_bank_statements.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - +from dateutil.relativedelta import relativedelta from odoo import models, fields, api, exceptions, _ from datetime import datetime, timedelta @@ -20,7 +19,6 @@ class PropertyBankStatements(models.Model): message = fields.Char('回单个性化信息') number = fields.Char('凭证号') extract = fields.Char('摘要') - is_put = fields.Boolean('是否推送') start_time = fields.Datetime('交易时间') contract_account = fields.Char(string="合同累计应收") contract_penalty = fields.Char(string="合同累计违约金") @@ -28,10 +26,27 @@ class PropertyBankStatements(models.Model): is_reconciliation = fields.Boolean('是否已对账') voucher_type = fields.Selection([('electronic_transfer', '电子转账凭证'), ('telegraphic_transfer', '电汇凭证')], string='凭证种类') remake = fields.Text('备注') + registered = fields.Float('挂账') property_ids = fields.Many2many('yuthon.property', string='物业地址') + bank_state = fields.Selection([('not_reconciled', '未对账'), ('reconciled', '已对账'), ('other', '其他')], string='状态', default='not_reconciled') - def unlink(self): - return super().unlink() + def other(self): + for rec in self: + rec.bank_state = 'other' + receivable_ids = self.env['property.accounts.receivable'].search([('lessee_id.name', '=', self.name_account)]) + property_list = [] + for property in self.property_ids: + property_list.append(property.name) + property_names = ",".join(property_list) + for receivable in receivable_ids: + receivable_log = f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {property_names} 的银行对账单状态修改为其他' + for record in self: + original_log = record.receivable_log or '' + if original_log: + new_log = f"{original_log}\n{receivable_log}" + else: + new_log = receivable_log + receivable.write({'receivable_log': new_log}) @api.onchange('name') def _onchange_name(self): @@ -51,8 +66,7 @@ class PropertyBankStatements(models.Model): self.property_ids = [(6, 0, property_ids)] self.contract_ids = [(6, 0, contract_ids.ids)] if contract_ids else [] - @api.onchange('property_ids') - def _onchange_property_or_contract_ids(self): + def binding_information(self): bank_list = [] if self.name: bank_id = self.env['property.bank.line'].search([('bank', '=', self.name)]) @@ -63,6 +77,22 @@ class PropertyBankStatements(models.Model): lessee_id = lease_contract_id.lessee_id bank_list.append((0, 0, {'name': self.name_account, 'user': lessee_id.name, 'bank': self.name,})) lessee_id.bank_ids = bank_list + + receivable_ids = self.env['property.accounts.receivable'].search([('lessee_id.name', '=', self.name_account)]) + property_list = [] + for property in self.property_ids: + property_list.append(property.name) + property_names = ",".join(property_list) + for receivable in receivable_ids: + receivable_log = f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {property_names} 的对账进行绑定新信息' + for record in self: + original_log = record.receivable_log or '' + if original_log: + new_log = f"{original_log}\n{receivable_log}" + else: + new_log = receivable_log + receivable.write({'receivable_log': new_log}) + @api.model def create(self, vals): record = super(PropertyBankStatements, self).create(vals) @@ -87,6 +117,29 @@ class PropertyBankStatements(models.Model): self.property_ids = [(6, 0, property_ids)] self.contract_ids = [(6, 0, contract_ids.ids)] if contract_ids else [] - def put_button_cancel(self): - for record in self: - record.is_put = False + + def handle_contract_penalty(self): + ''' + 处理合同违约金 + :param record: property.bank.statements 记录 + :return: + ''' + record = self.env["property.bank.statements"].browse( + self._context.get('active_ids', self._context.get('active_id'))) + for contract_id in record.contract_ids: + receivable_id = self.env['property.accounts.receivable'].search([('contract_id', '=', contract_id.id)]) + if receivable_id: + dt = datetime.strptime(str(record.start_time), '%Y-%m-%d %H:%M:%S').date() # 流水交易时间 + due = datetime.strptime(str(receivable_id.due_date), '%Y-%m-%d').date() + relativedelta(months=1, day=1) # 应收日期 + # 判断是否违约 + if receivable_id.submitted and not receivable_id.is_reconciliation or not receivable_id.is_suspend: + original_amount = (due - dt).days * receivable_id.original_amount * float(receivable_id.contract_id.percentage_liquidated_damages.name) + self.env['property.penalty.list'].create({ + 'contract_id': contract_id.id, + 'property_id': contract_id.lease_ids[0].address_id.id, + 'lessee_id': contract_id.lessee_id.id, + 'original_amount': original_amount + }) + receivable_id.write({'penalty':original_amount}) + receivable_id.is_reconciliation = True + diff --git a/yuthon_property/models/property_rent_list.py b/yuthon_property/models/property_rent_list.py index a0d058108..4468f64bb 100644 --- a/yuthon_property/models/property_rent_list.py +++ b/yuthon_property/models/property_rent_list.py @@ -42,4 +42,7 @@ class PropertyRentList(models.Model): return super(PropertyRentList, self).write(vals) def unlink(self): + receivable_ids = self.env['property.accounts.receivable'].search([('lessee_id', '=', self.lessee_id.id)]) + for receivable in receivable_ids: + receivable.write({'receivable_log': f'当前登录人{self.env.user.name}于{fields.Datetime.now()}将物业为 {self.property_id.name} 的租金列表进行删除'}) return super().unlink() diff --git a/yuthon_property/security/ir.model.access.csv b/yuthon_property/security/ir.model.access.csv index 2b67f55a3..6ec46bc1c 100644 --- a/yuthon_property/security/ir.model.access.csv +++ b/yuthon_property/security/ir.model.access.csv @@ -87,5 +87,6 @@ access_property_floor_setting,property_floor_setting,model_property_floor_settin access_property_evaluation_plan,property_evaluation_plan,model_property_evaluation_plan,base.group_user,1,1,1,1 access_evaluation_company,evaluation_company,model_evaluation_company,base.group_user,1,1,1,1 access_evaluation_plan_wizard,evaluation_plan_wizard,model_evaluation_plan_wizard,base.group_user,1,1,1,1 +access_receivable_log_wizard, receivable.log.wizard,model_receivable_log_wizard,base.group_user,1,1,1,1 access_amount_way,amount_way,model_amount_way,base.group_user,1,1,1,1 access_property_summary_report, property_summary_report,model_property_summary_report,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/yuthon_property/views/property_accounts_receivable_views.xml b/yuthon_property/views/property_accounts_receivable_views.xml index 39b55ae5c..9bd749557 100644 --- a/yuthon_property/views/property_accounts_receivable_views.xml +++ b/yuthon_property/views/property_accounts_receivable_views.xml @@ -5,13 +5,17 @@ + decoration-success="charge_status == 'fully_paid'" limit="20"> +
+
+ @@ -24,10 +28,12 @@ + -