@@ -1,5 +1,7 @@
|
||||
from odoo import models, fields, api
|
||||
import xlwt
|
||||
from odoo.modules import get_module_resource
|
||||
|
||||
|
||||
class PropertyAccountsReceivable(models.Model):
|
||||
_name = 'property.accounts.receivable'
|
||||
@@ -40,19 +42,79 @@ class PropertyAccountsReceivable(models.Model):
|
||||
def unlink(self):
|
||||
return super().unlink()
|
||||
|
||||
def report_button_xls(self):
|
||||
workbook = xlwt.Workbook() # 创建一个工作簿
|
||||
worksheet = workbook.add_sheet('Sheet1')
|
||||
for record in self:
|
||||
worksheet.write(1, 0, record.original_amount)
|
||||
action = {
|
||||
'type': 'ir.actions.act_url', # 表示将执行一个客户端动作。
|
||||
'tag': 'self',
|
||||
'context': dict({
|
||||
'url': 'yuthon_property/static/others/property_bases_account.xlsx',
|
||||
'module': 'yuthon_property', # 指定模块名称
|
||||
'content_type': 'application/vnd.ms-excel'
|
||||
}, **self._context)
|
||||
}
|
||||
return action
|
||||
|
||||
def style_excel(self):
|
||||
# 定义样式,可根据需要修改
|
||||
report_no_style = xlwt.XFStyle()
|
||||
report_title_style = xlwt.XFStyle()
|
||||
style_white = xlwt.XFStyle()
|
||||
report_borders_style = xlwt.XFStyle()
|
||||
|
||||
# 设置样式属性,例如字体、边框等
|
||||
# 这里简单示例,可根据实际需求完善
|
||||
font = xlwt.Font()
|
||||
font.bold = True
|
||||
report_title_style.font = font
|
||||
|
||||
borders = xlwt.Borders()
|
||||
borders.left = xlwt.Borders.THIN
|
||||
borders.right = xlwt.Borders.THIN
|
||||
borders.top = xlwt.Borders.THIN
|
||||
borders.bottom = xlwt.Borders.THIN
|
||||
report_borders_style.borders = borders
|
||||
|
||||
return [report_no_style, report_title_style, style_white, report_borders_style]
|
||||
|
||||
def download_template_with_data(self):
|
||||
# 获取当前记录
|
||||
record = self
|
||||
|
||||
# 通用样式
|
||||
workbook = xlwt.Workbook() # 创建一个工作簿
|
||||
worksheet = workbook.add_sheet('Sheet1') # 为工作簿添加一个页签
|
||||
|
||||
report_no_style = self.style_excel()[0]
|
||||
report_title_style = self.style_excel()[1]
|
||||
style_white = self.style_excel()[2]
|
||||
report_borders_style = self.style_excel()[3]
|
||||
|
||||
# 这里假设从当前记录中获取数据,可根据实际模型字段修改
|
||||
report_data = record
|
||||
|
||||
# 设置列宽
|
||||
for col in range(0, 7):
|
||||
worksheet.col(col).width = 3000
|
||||
|
||||
# 写入表头
|
||||
header = ['字段1', '字段2', '字段3', '字段4', '字段5', '字段6', '字段7']
|
||||
for col, value in enumerate(header):
|
||||
worksheet.write(0, col, value, report_borders_style)
|
||||
|
||||
# 写入数据行
|
||||
# 假设模型中有多个相关记录,可根据实际情况修改
|
||||
row = 1
|
||||
for record in self:
|
||||
worksheet.write(row, 0, record.lessee_id.name, report_borders_style)
|
||||
# worksheet.write(row, 1, record.field2, report_borders_style)
|
||||
# worksheet.write(row, 2, record.field3, report_borders_style)
|
||||
# worksheet.write(row, 3, record.field4, report_borders_style)
|
||||
# worksheet.write(row, 4, record.field5, report_borders_style)
|
||||
# worksheet.write(row, 5, record.field6, report_borders_style)
|
||||
# worksheet.write(row, 6, record.field7, report_borders_style)
|
||||
row += 1
|
||||
|
||||
# 保存文件
|
||||
template_path = get_module_resource('yuthon_property', 'static', 'tmpl', 'fapiaojibenxinxi.xlsx')
|
||||
workbook.save(template_path)
|
||||
|
||||
# # 导出动作
|
||||
# action = {
|
||||
# 'type': 'ir.actions.act_url', # 表示将执行一个客户端动作。
|
||||
# 'tag': 'self',
|
||||
# 'context': dict({
|
||||
# 'url': 'yuthon_property/static/tmpl/fapiaojibenxinxi.xlsx',
|
||||
# 'module': 'yuthon_property', # 指定模块名称
|
||||
# 'content_type': 'application/vnd.ms-excel'
|
||||
# }, **self._context)
|
||||
# }
|
||||
# return action
|
||||
|
||||
@@ -8,9 +8,18 @@ class PropertyBankStatements(models.Model):
|
||||
_name = 'property.bank.statements'
|
||||
_description = '银行流水'
|
||||
|
||||
name = fields.Char('账户卡号')
|
||||
name = fields.Char('对方账号')
|
||||
company_id = fields.Many2one('yuthon.property.company', string="收款账户")
|
||||
name_account = fields.Char('户名')
|
||||
name_account = fields.Char('对方户名')
|
||||
bank_branch = fields.Char('对方开户机构')
|
||||
bank_number = fields.Char('对方行号')
|
||||
bank_name = fields.Char('对方行名')
|
||||
account_code = fields.Char('账户明细编号')
|
||||
journal_date = fields.Date('记账日期')
|
||||
purpose = fields.Char('用途')
|
||||
message = fields.Char('回单个性化信息')
|
||||
number = fields.Char('凭证号')
|
||||
extract = fields.Char('摘要')
|
||||
start_time = fields.Datetime('交易时间')
|
||||
contract_account = fields.Char(string="合同累计应收")
|
||||
contract_penalty = fields.Char(string="合同累计违约金")
|
||||
|
||||
Binary file not shown.
@@ -73,11 +73,10 @@
|
||||
<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">
|
||||
<![CDATA[
|
||||
action = env.ref('yuthon_property.template_downloads_invoicing_basic_action').read()[0]
|
||||
]]>
|
||||
</field>
|
||||
<field name="code">action = model.download_template_with_data()</field>
|
||||
<!-- <![CDATA[-->
|
||||
<!-- action = env.ref('yuthon_property.template_downloads_invoicing_basic_action').read()[0]-->
|
||||
<!-- ]]>-->
|
||||
</record>
|
||||
<record id="template_downloads_invoicing_line_action" model="ir.actions.act_url">
|
||||
<field name="name">发票明细信息模板下载</field>
|
||||
|
||||
@@ -8,12 +8,21 @@
|
||||
<field name="start_time"/>
|
||||
<field name="company_id"/>
|
||||
<field name="name"/>
|
||||
<field name="bank_name"/>
|
||||
<field name="name_account"/>
|
||||
<field name="purpose"/>
|
||||
<field name="journal_date"/>
|
||||
<field name="bank_branch"/>
|
||||
<field name="extract"/>
|
||||
<field name="account_code"/>
|
||||
<field name="remake"/>
|
||||
<field name="original_amount"/>
|
||||
<field name="contract_account"/>
|
||||
<field name="contract_penalty"/>
|
||||
<field name="property_ids" widget="many2many_tags"/>
|
||||
<field name="bank_number" optional="hide"/>
|
||||
<field name="message" optional="hide"/>
|
||||
<field name="number"/>
|
||||
<field name="voucher_type"/>
|
||||
<button name="unlink" type="object" string="删除" class="btn btn-primary"/>
|
||||
</tree>
|
||||
|
||||
@@ -25,9 +25,23 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_property_penalty_list_search" model="ir.ui.view">
|
||||
<field name="name">property.penalty.list.search</field>
|
||||
<field name="model">property.penalty.list</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="property_id"/>
|
||||
<field name="lessee_id"/>
|
||||
<group expand="0" string="group_by">
|
||||
<filter name="group_property_id" string="物业" context="{'group_by':'property_id'}"/>
|
||||
<filter name="group_lessee_id" string="承租方" context="{'group_by':'lessee_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_property_penalty_list_action" model="ir.actions.act_window">
|
||||
<field name="name">违约金列表</field>
|
||||
<field name="res_model">property.penalty.list</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -25,21 +25,37 @@ class PropertyStatementsWizard(models.Model):
|
||||
sh = book.sheet_by_index(0)
|
||||
for rx in range(1, sh.nrows):
|
||||
row = sh.row(rx)
|
||||
self.property_bank_statements_data(row)
|
||||
if self.selection_bank == 'js':
|
||||
self.property_bank_statements_jh_data(row)
|
||||
elif self.selection_bank == 'gs':
|
||||
self.property_bank_statements_gc_data(row)
|
||||
|
||||
def property_bank_statements_data(self, row):
|
||||
def property_bank_statements_jh_data(self, row):
|
||||
contract_ids = self.env['property.lease.contract']
|
||||
if row[2].value:
|
||||
formatted_date = self.convert_date_format(row[2].value)
|
||||
start_time = pd.to_datetime(formatted_date)
|
||||
else:
|
||||
start_time = None
|
||||
|
||||
if row[10].value:
|
||||
formatted_date = self.convert_date_format1(row[10].value)
|
||||
journal_date = pd.to_datetime(formatted_date)
|
||||
else:
|
||||
journal_date = None
|
||||
|
||||
name = row[8].value
|
||||
company_id = self.env['yuthon.property.company'].search([('name', '=', row[1].value)])
|
||||
name_account = row[7].value
|
||||
voucher_type = row[15].value
|
||||
voucher_type_dict = {'电子转账凭证': 'electronic_transfer', '电汇凭证': 'telegraphic_transfer'}
|
||||
voucher_type = voucher_type_dict.get(voucher_type)
|
||||
remake = row[12].value
|
||||
original_amount = row[4].value
|
||||
bank_branch = row[9].value
|
||||
account_code = row[13].value
|
||||
number = row[16].value
|
||||
extract = row[11].value
|
||||
property_ids = []
|
||||
bank_data = {
|
||||
'name': name,
|
||||
@@ -48,10 +64,59 @@ class PropertyStatementsWizard(models.Model):
|
||||
'company_id': company_id.id,
|
||||
'start_time': start_time,
|
||||
'name_account': name_account,
|
||||
'voucher_type': voucher_type
|
||||
'voucher_type': voucher_type,
|
||||
'original_amount':original_amount,
|
||||
'journal_date':journal_date,
|
||||
'bank_branch':bank_branch,
|
||||
'extract':extract,
|
||||
'account_code':account_code,
|
||||
'number':number,
|
||||
'remake':remake,
|
||||
}
|
||||
self.env['property.bank.statements'].create(bank_data)
|
||||
if float(row[3].value) != 0:
|
||||
self.env['property.bank.statements'].create(bank_data)
|
||||
else:
|
||||
pass
|
||||
|
||||
def convert_date_format(self,date_str):
|
||||
pattern = r'(\d{4})(\d{2})(\d{2}) (\d{2}:\d{2}:\d{2})'
|
||||
return re.sub(pattern, r'\1/\2/\3 \4', date_str)
|
||||
|
||||
def convert_date_format1(self,date_str):
|
||||
pattern = r'(\d{4})(\d{2})(\d{2})'
|
||||
return re.sub(pattern, r'\1/\2/\3', date_str)
|
||||
|
||||
def property_bank_statements_gc_data(self, row):
|
||||
message = row[18].value
|
||||
if row[2].value:
|
||||
start_time = pd.to_datetime(row[2].value)
|
||||
else:
|
||||
start_time = None
|
||||
name_account = row[3].value
|
||||
name = row[4].value
|
||||
purpose = row[5].value
|
||||
extract = row[6].value
|
||||
remake = row[7].value
|
||||
original_amount = row[8].value.replace(',', '')
|
||||
bank_number = row[12].value
|
||||
if row[13].value:
|
||||
journal_date = pd.to_datetime(row[13].value)
|
||||
else:
|
||||
journal_date = None
|
||||
number = row[15].value
|
||||
bank_name = row[21].value
|
||||
bank_data = {
|
||||
'name': name,
|
||||
'bank_name':bank_name,
|
||||
'start_time': start_time,
|
||||
'name_account': name_account,
|
||||
'original_amount': original_amount,
|
||||
'journal_date': journal_date,
|
||||
'number': number,
|
||||
'remake': remake,
|
||||
'bank_number':bank_number,
|
||||
'purpose':purpose,
|
||||
'extract':extract,
|
||||
'message':message,
|
||||
}
|
||||
self.env['property.bank.statements'].create(bank_data)
|
||||
@@ -37,15 +37,62 @@ class PropertyBankStatements(models.Model):
|
||||
'original_amount':original_amount
|
||||
})
|
||||
receivable_id.is_reconciliation = True
|
||||
|
||||
if self.name:
|
||||
bank_id = self.env['property.bank.line'].search([('bank', '=', self.name)])
|
||||
total_rent_month = 0
|
||||
if bank_id:
|
||||
tenant_id = bank_id.tenant_id
|
||||
# 应收租金
|
||||
rent_ids = self.env['property.rent.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
# 应收押金
|
||||
deposit_ids = self.env['property.deposit.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
# 应收管理费
|
||||
management_ids = self.env['property.management.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
# 应收水费
|
||||
water_ids = self.env['property.water.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
# 应收电费
|
||||
electricity_ids = self.env['property.tariff.list'].search([('lessee_id', '=', tenant_id.id)])
|
||||
|
||||
def create_reconciliation_vals(ids):
|
||||
nonlocal total_rent_month
|
||||
vals_list = []
|
||||
for record in ids:
|
||||
property_id = record.property_id.id if record.property_id else False
|
||||
contract_id = record.contract_id.id if record.contract_id else False
|
||||
original_amount = record.original_amount if record.original_amount else 0
|
||||
vals = {
|
||||
'property_id': property_id,
|
||||
'contract_id': contract_id,
|
||||
'rent_month': original_amount,
|
||||
'rent': original_amount,
|
||||
}
|
||||
# 使用 (0, 0, vals) 格式表示创建新记录
|
||||
total_rent_month += original_amount
|
||||
vals_list.append((0, 0, vals))
|
||||
return vals_list
|
||||
|
||||
all_vals = []
|
||||
all_vals.extend(create_reconciliation_vals(rent_ids))
|
||||
all_vals.extend(create_reconciliation_vals(deposit_ids))
|
||||
all_vals.extend(create_reconciliation_vals(management_ids))
|
||||
all_vals.extend(create_reconciliation_vals(water_ids))
|
||||
all_vals.extend(create_reconciliation_vals(electricity_ids))
|
||||
|
||||
context = {
|
||||
"default_account": self.name,
|
||||
"default_actual_total":self.original_amount,
|
||||
"default_reconciliation_line_ids": all_vals,
|
||||
"default_receivable_total": total_rent_month
|
||||
}
|
||||
|
||||
return {
|
||||
"type": "ir.actions.act_window",
|
||||
"name": "对账弹窗",
|
||||
"res_model": "property.reconciliation.wizard",
|
||||
"view_mode": "form",
|
||||
"target": "new",
|
||||
"context": {
|
||||
"default_account": self.name,
|
||||
},
|
||||
"context": context,
|
||||
}
|
||||
|
||||
class PropertyBankLine(models.Model):
|
||||
|
||||
@@ -84,10 +84,24 @@
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.batch_push_deposit()</field>
|
||||
</record>
|
||||
<record id="property_deposit_search" model="ir.ui.view">
|
||||
<field name="name">property.deposit.list.search</field>
|
||||
<field name="model">property.deposit.list</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="property_id"/>
|
||||
<field name="lessee_id"/>
|
||||
<group expand="0" string="group_by">
|
||||
<filter name="group_property_id" string="物业" context="{'group_by':'property_id'}"/>
|
||||
<filter name="group_lessee_id" string="承租方" context="{'group_by':'lessee_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="property_deposit_list_action" model="ir.actions.act_window">
|
||||
<field name="name">押金列表</field>
|
||||
<field name="res_model">property.deposit.list</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
<field name="domain">[('is_push', '=', False)]</field>
|
||||
</record>
|
||||
<!--电费-->
|
||||
@@ -290,6 +304,20 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="property_management_list_search" model="ir.ui.view">
|
||||
<field name="name">property.management.list.search</field>
|
||||
<field name="model">property.management.list</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="property_id"/>
|
||||
<field name="lessee_id"/>
|
||||
<group expand="0" string="group_by">
|
||||
<filter name="group_property_id" string="物业" context="{'group_by':'property_id'}"/>
|
||||
<filter name="group_lessee_id" string="承租方" context="{'group_by':'lessee_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="all_property_management_push" model="ir.actions.server">
|
||||
<field name="name">批量推送</field>
|
||||
<field name="model_id" ref="yuthon_property.model_property_management_list"/>
|
||||
@@ -300,7 +328,7 @@
|
||||
<record id="property_management_list_action" model="ir.actions.act_window">
|
||||
<field name="name">管理费列表</field>
|
||||
<field name="res_model">property.management.list</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
<field name="domain">[('is_push', '=', False)]</field>
|
||||
</record>
|
||||
<!--应收账单 -->
|
||||
|
||||
@@ -318,25 +318,26 @@
|
||||
web_icon="yuthon_work_brand,static/description/salary.png"
|
||||
groups="yuthon_salary.group_salary_user"
|
||||
sequence="9"/>
|
||||
<menuitem id="human_work_entry_board"
|
||||
name="工作分录"
|
||||
parent="human_resources_salary_root_board"
|
||||
action="hr_work_entry.hr_work_entry_action"
|
||||
sequence="5"/>
|
||||
<!-- <menuitem id="human_work_entry_board"-->
|
||||
<!-- name="工作分录"-->
|
||||
<!-- parent="human_resources_salary_root_board"-->
|
||||
<!-- action="hr_work_entry.hr_work_entry_action"-->
|
||||
<!-- sequence="5"/>-->
|
||||
<menuitem id="human_pay_slips_root_board"
|
||||
name="工资条"
|
||||
parent="human_resources_salary_root_board"
|
||||
sequence="7"/>
|
||||
<menuitem id="human_pay_be_paid_board"
|
||||
name="待支付"
|
||||
parent="human_pay_slips_root_board"
|
||||
action="hr_payroll.hr_payslip_action_view_to_pay"
|
||||
sequence="1"/>
|
||||
<menuitem id="human_all_pay_slips_board"
|
||||
name="所有工资条"
|
||||
parent="human_pay_slips_root_board"
|
||||
action="hr_payroll.action_view_hr_payslip_month_form"
|
||||
sequence="3"/>
|
||||
sequence="7"/>
|
||||
<!-- <menuitem id="human_pay_be_paid_board"-->
|
||||
<!-- name="待支付"-->
|
||||
<!-- parent="human_pay_slips_root_board"-->
|
||||
<!-- action="hr_payroll.hr_payslip_action_view_to_pay"-->
|
||||
<!-- sequence="1"/>-->
|
||||
<!-- <menuitem id="human_all_pay_slips_board"-->
|
||||
<!-- name="所有工资条"-->
|
||||
<!-- parent="human_pay_slips_root_board"-->
|
||||
<!-- action="hr_payroll.action_view_hr_payslip_month_form"-->
|
||||
<!-- sequence="3"/>-->
|
||||
<menuitem id="hr_payroll_structure_type_board"
|
||||
name="职级类型"
|
||||
parent="human_resources_salary_root_board"
|
||||
|
||||
Reference in New Issue
Block a user