Merge branch 'dev' of https://gitee.com/jinan-pengyusen-data/gzth into dev
This commit is contained in:
@@ -4,6 +4,7 @@ from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
import logging
|
||||
from datetime import datetime, date, time, timedelta
|
||||
import re
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -52,7 +53,114 @@ class SoongWorkflowRecord(models.Model):
|
||||
member_of_department = fields.Boolean("是否是本部门数据", compute='_compute_part_of_department', search='_search_part_of_department')
|
||||
|
||||
def admin_end(self):
|
||||
pass
|
||||
workflow_ids = self.env["soong.workflow.record"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id', []))
|
||||
)
|
||||
current_datetime = fields.Datetime.now()
|
||||
for workflow in workflow_ids:
|
||||
record_id = self.env[workflow.res_model].search([('id', '=', workflow.res_id)])
|
||||
if hasattr(record_id, 'user_id') and record_id.user_id:
|
||||
user_id = record_id.user_id
|
||||
elif hasattr(record_id, 'users_id') and record_id.users_id:
|
||||
user_id = record_id.users_id
|
||||
if not record_id:
|
||||
continue
|
||||
# 触发模型对应的结束方法
|
||||
end_node = self.env["soong.workflow.node"].search(
|
||||
[('workflow_id', '=', workflow.workflow_id.id), ('is_end', '=', True)],
|
||||
limit=1
|
||||
)
|
||||
end_btn = self.env["soong.workflow.node.button"].search(
|
||||
[('node_id', '=', end_node.id),
|
||||
('name', '=', '结束')],
|
||||
limit=1
|
||||
)
|
||||
if end_btn:
|
||||
self.execute_button_code(end_btn.id, workflow.res_model, workflow.res_id)
|
||||
node_id = self.env["soong.workflow.node"].search(
|
||||
[('workflow_id', '=', workflow.workflow_id.id),
|
||||
('name', '=', record_id.state)],
|
||||
limit=1
|
||||
)
|
||||
# 修改日志
|
||||
log_records = None
|
||||
if record_id.log_ids2:
|
||||
log_records = record_id.log_ids2
|
||||
elif record_id.log_ids:
|
||||
log_records = record_id.log_ids
|
||||
|
||||
log_model = "soong.workflow.log"
|
||||
if record_id.log_ids2:
|
||||
log_model = "soong.workflow.log2"
|
||||
elif record_id.log_ids:
|
||||
log_model = "soong.workflow.log"
|
||||
|
||||
if log_records:
|
||||
log_records[-1].write({
|
||||
'approval_state': '3',
|
||||
'lase_click_date': current_datetime,
|
||||
})
|
||||
else:
|
||||
self.env[log_model].create({
|
||||
'done_by': user_id.id,
|
||||
'node_id': node_id.id if node_id else False,
|
||||
'workflow_id': workflow.workflow_id.id,
|
||||
'model': workflow.res_model,
|
||||
'res_id': workflow.res_id,
|
||||
'approval_state': '3',
|
||||
'lase_click_date': current_datetime,
|
||||
'sequence': 99,
|
||||
})
|
||||
|
||||
workflow.approve_state = 'end'
|
||||
|
||||
def execute_button_code(self, button_id, res_model, res_id):
|
||||
|
||||
"""
|
||||
执行按钮code字段中的代码,动态解析并验证方法是否存在
|
||||
:param button_id: soong.workflow.node.button的记录ID
|
||||
:param res_model: 模型名称
|
||||
"""
|
||||
button = self.env["soong.workflow.node.button"].browse(button_id)
|
||||
if not button or not button.code:
|
||||
return
|
||||
workflow = button.node_id.workflow_id if button.node_id else None
|
||||
obj = self.env[res_model].browse(res_id)
|
||||
if not obj:
|
||||
raise UserError(f"找不到{res_model}模型中ID为{res_id}的记录")
|
||||
# 从code中提取obj调用的方法名(匹配obj.xxx()格式)
|
||||
method_match = re.search(r'obj\.(\w+)\(\)', button.code)
|
||||
if not method_match:
|
||||
raise UserError("该按钮没有配置结束的方法,请先配置!")
|
||||
|
||||
# 准备代码执行的上下文环境
|
||||
local_context = {
|
||||
'time': time,
|
||||
'date': date,
|
||||
'datetime': datetime,
|
||||
'timedelta': timedelta,
|
||||
'env': self.env,
|
||||
'model': self.env[res_model],
|
||||
'obj': obj,
|
||||
'user': self.env.user,
|
||||
'workflow': workflow,
|
||||
'syslog': self._log_debug,
|
||||
'warning': self._get_warning_exception,
|
||||
'action': None
|
||||
}
|
||||
exec(button.code, globals(), local_context)
|
||||
# 如果有返回的action,处理它
|
||||
if local_context.get('action'):
|
||||
return local_context['action']
|
||||
|
||||
def _log_debug(self, message):
|
||||
"""用于syslog的实现"""
|
||||
self.env.logger.debug(message)
|
||||
|
||||
def _get_warning_exception(self, message):
|
||||
"""用于warning的实现"""
|
||||
return Warning(message)
|
||||
|
||||
|
||||
def update_self_users_ids(self):
|
||||
record_ids = self.env["soong.workflow.record"].browse(
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
decoration-danger="approve_state == 'end'" delete="false"
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1">
|
||||
<header>
|
||||
<button name="admin_end" type="object" string="管理员强制结束" class="oe_highlight"/>
|
||||
<button name="admin_end" type="object" string="管理员强制结束" class="oe_highlight" groups="soong_workflow.group_soong_workflow_manager"/>
|
||||
<button name="delete_record" type="object" string="删除" class="oe_highlight" groups="soong_workflow.group_soong_workflow_manager"/>
|
||||
</header>
|
||||
<field name="code"/>
|
||||
@@ -172,7 +172,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="domain">[('reclaim_state', '=', False), '|', ('approvals_group_id.name', '=', '人力资源'), ('approvals_group_id.name', '=', '考勤')]</field>
|
||||
<field name="domain">[('reclaim_state', '=', False), '|', ('approvals_group_id.name', '=', '人力资源'), ('approvals_group_id.name', '=', '考勤'), ('approve_state', '!=', 'start')]</field>
|
||||
<field name="search_view_id" ref="soong_workflow_record_search"/>
|
||||
</record>
|
||||
<record id="soong_workflow_other_record_action" model="ir.actions.act_window">
|
||||
|
||||
@@ -24,7 +24,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
node_link_len = fields.Char(string="转交2")
|
||||
is_supervising = fields.Boolean(string="是否督办")
|
||||
comment_note_id = fields.Many2one('soong.note', string="常用意见", default='妥否,呈领导审批')
|
||||
comment_note = fields.Char(string="意见")
|
||||
comment_note = fields.Char(string="意见", default='同意')
|
||||
comment = fields.Char(compute='_compute_comment', store=True)
|
||||
state_list = fields.Char(string="状态列表")
|
||||
record_id = fields.Integer()
|
||||
@@ -492,13 +492,54 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)]
|
||||
return self.node_btn_id.with_context(cx).run()
|
||||
if self.node_btn_name == '结束':
|
||||
record_id.log_ids[-1].comment = self.comment
|
||||
record_id.log_ids[-1].approval_state = "3"
|
||||
record_id.log_ids[-1].lase_click_date = fields.Datetime.now()
|
||||
record_id.work_end = True
|
||||
self.env['soong.workflow.record'].search([('code', '=', record_id.code)]).write({'approve_state': 'end',
|
||||
"employee_ids": False,
|
||||
"node_id": False,})
|
||||
current_user = self.env.user
|
||||
current_datetime = fields.Datetime.now()
|
||||
log_records = record_id.log_ids
|
||||
if record_id.log_ids2:
|
||||
log_records = record_id.log_ids2
|
||||
elif record_id.log_ids:
|
||||
log_records = record_id.log_ids
|
||||
|
||||
if log_records:
|
||||
# 查找当前用户的日志记录并更新
|
||||
user_log = log_records.filtered(lambda log: log.done_by == current_user)
|
||||
if user_log:
|
||||
user_log.write({
|
||||
'comment': self.comment,
|
||||
'approval_state': "3",
|
||||
'lase_click_date': current_datetime
|
||||
})
|
||||
last_log = log_records[-1] if log_records else None
|
||||
if last_log:
|
||||
same_name_logs = log_records.filtered(
|
||||
lambda log: log.name == last_log.name
|
||||
and log.node_btn_name == '4'
|
||||
and log.id != last_log.id
|
||||
)
|
||||
|
||||
# 判断是否需要更新工作流状态
|
||||
if same_name_logs:
|
||||
all_approved = all(log.approval_state == '3' for log in same_name_logs)
|
||||
all_approved = all_approved and (last_log.approval_state == '3')
|
||||
if all_approved:
|
||||
# 所有符合条件的记录都已批准,更新工作流状态
|
||||
self.env['soong.workflow.record'].search([
|
||||
('code', '=', record_id.code)
|
||||
]).write({
|
||||
'approve_state': 'end',
|
||||
'employee_ids': False,
|
||||
'node_id': False,
|
||||
})
|
||||
record_id.work_end = True
|
||||
else:
|
||||
self.env['soong.workflow.record'].search([
|
||||
('code', '=', record_id.code)
|
||||
]).write({
|
||||
'approve_state': 'end',
|
||||
'employee_ids': False,
|
||||
'node_id': False,
|
||||
})
|
||||
record_id.work_end = True
|
||||
|
||||
# 给申请人发消息
|
||||
biz_record = self.env[self.res_model].browse(self.res_id)
|
||||
|
||||
@@ -17,33 +17,55 @@ class SoongWorkflowRecordDeleteWizard(models.TransientModel):
|
||||
def add_comment(self):
|
||||
for record in self.record_ids:
|
||||
if self.name == "确认删除":
|
||||
if record.reclaim_state is False:
|
||||
self.env["soong.workflow.record"].sudo().search([("id", "=", record.id)]).write({
|
||||
"reclaim_state": True
|
||||
})
|
||||
# 首先检查工作流记录是否存在
|
||||
workflow_record = self.env["soong.workflow.record"].sudo().search([("id", "=", record.id)], limit=1)
|
||||
if not workflow_record:
|
||||
continue
|
||||
# 删除假期额度里面的对应的流程记录
|
||||
related_detail_models = [
|
||||
'vacation.leave.line',
|
||||
'vacation.over.line',
|
||||
'vacation.meal.line',
|
||||
'vacation.medical.line'
|
||||
]
|
||||
for model_name in related_detail_models:
|
||||
detail_model = self.env[model_name].sudo()
|
||||
related_detail_records = detail_model.search([
|
||||
('workflow_record_id', '=', workflow_record.id)
|
||||
])
|
||||
if related_detail_records:
|
||||
related_detail_records.unlink()
|
||||
|
||||
if not record.reclaim_state:
|
||||
workflow_record.write({"reclaim_state": True})
|
||||
|
||||
# 处理工作流日志
|
||||
log_ids = self.env["soong.workflow.log"].sudo().search([("code", "=", record.code)])
|
||||
for log_id in log_ids:
|
||||
log_id.sudo().write({
|
||||
"active": False
|
||||
})
|
||||
target_model = self.env[record.res_model]
|
||||
target_record = target_model.sudo().browse(record.res_id)
|
||||
if target_model._name in ["hr.leave.batch"]:
|
||||
if target_record.leave_ids:
|
||||
for leave in target_record.leave_ids:
|
||||
leave.sudo().with_context(from_cancel_wizard=True).write({
|
||||
"state": "confirm",
|
||||
"active": False
|
||||
})
|
||||
if target_record.hour_leave_ids:
|
||||
for hour_leave in target_record.hour_leave_ids:
|
||||
hour_leave.sudo().with_context(from_cancel_wizard=True).write({
|
||||
"state": "confirm",
|
||||
"active": False
|
||||
})
|
||||
target_record.write({'active': False})
|
||||
log_id.sudo().write({"active": False})
|
||||
|
||||
if record.res_model and record.res_id:
|
||||
target_model = self.env[record.res_model]
|
||||
target_record = target_model.sudo().browse(record.res_id).exists()
|
||||
if target_record:
|
||||
if target_model._name in ["hr.leave.batch"]:
|
||||
if target_record.leave_ids:
|
||||
for leave in target_record.leave_ids:
|
||||
leave.sudo().with_context(from_cancel_wizard=True).write({
|
||||
"state": "confirm",
|
||||
"active": False
|
||||
})
|
||||
if target_record.hour_leave_ids:
|
||||
for hour_leave in target_record.hour_leave_ids:
|
||||
hour_leave.sudo().with_context(from_cancel_wizard=True).write({
|
||||
"state": "confirm",
|
||||
"active": False
|
||||
})
|
||||
# 确保在写入前记录仍然存在
|
||||
if target_record.exists():
|
||||
target_record.write({'active': False})
|
||||
else:
|
||||
self.env["soong.workflow.record"].sudo().search(
|
||||
[("id", "=", record.id), ('reclaim_state', "=", True)]).write({
|
||||
"active": False
|
||||
})
|
||||
workflow_record = self.env["soong.workflow.record"].sudo().search(
|
||||
[("id", "=", record.id), ('reclaim_state', "=", True)], limit=1)
|
||||
if workflow_record:
|
||||
workflow_record.write({"active": False})
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{_ as e}from"./index-CimcMLIq.js";const r={};function c(n,t){return null}const o=e(r,[["render",c]]);export{o as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{B as _,E as i,C as d,D as v}from"./requests-DdoUQiv8.js";import{_ as p,r as h,o as m,u as y,h as f,i as l,g as a,t,k,l as g}from"./index-CimcMLIq.js";const w=r=>_("/yuthon/yuthon/will/task",{id:r}),x={class:"container"},B={class:"meeting-header"},C={class:"title"},q={class:"time"},D={class:"location"},E={__name:"Journey",setup(r){const u=y(),e=h({});return m(async()=>{try{const s=parseInt(u.query.id),n=await w(s);e.value=n.data}catch(s){i("获取任务详情失败"),console.error(s)}}),(s,n)=>{const o=v,c=d;return g(),f("div",x,[l("div",B,[l("div",C,t(e.value.name),1),l("div",q,t(e.value.start_date)+" "+t(e.value.start_date_week)+" "+t(e.value.request_hour_from)+" - "+t(e.value.request_hour_to),1),l("div",D,"地址: "+t(e.value.address),1)]),a(c,null,{default:k(()=>[a(o,{title:"组织人",value:e.value.user_id},null,8,["value"]),a(o,{title:"参与人",value:"共"+(e.value.employee_ids?.length||0)+"人"},null,8,["value"]),a(o,{title:"描述",value:e.value.remarks},null,8,["value"]),a(o,{title:"任务编号",value:e.value.code},null,8,["value"])]),_:1})])}}},N=p(E,[["__scopeId","data-v-0aa7162a"]]);export{N as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{v as B,t as A,c as p,H as E,I as V,j as w,n as b,F as y,B as q,E as H,C as O,D as j}from"./requests-DdoUQiv8.js";import{d as x,g as a,T as G,F as I,s as K,_ as M,r as R,o as J,u as Q,h as S,i as f,t as k,k as P,l as C,p as U,q as W}from"./index-CimcMLIq.js";import{I as X}from"./index-BJ3ARmPk.js";const[Y,T]=p("tag"),Z={size:String,mark:Boolean,show:A,type:B("default"),color:String,plain:Boolean,round:Boolean,textColor:String,closeable:Boolean};var ee=x({name:Y,props:Z,emits:["close"],setup(t,{slots:e,emit:u}){const l=o=>{o.stopPropagation(),u("close",o)},r=()=>t.plain?{color:t.textColor||t.color,borderColor:t.color}:{color:t.textColor,background:t.color},d=()=>{var o;const{type:m,mark:i,plain:c,round:v,size:s,closeable:_}=t,g={mark:i,plain:c,round:v};s&&(g[s]=s);const h=_&&a(V,{name:"cross",class:[T("close"),E],onClick:l},null);return a("span",{style:r(),class:T([g,m])},[(o=e.default)==null?void 0:o.call(e),h])};return()=>a(G,{name:t.closeable?"van-fade":void 0},{default:()=>[t.show?d():null]})}});const te=w(ee),[ae,n]=p("card"),ne={tag:String,num:b,desc:String,thumb:String,title:String,price:b,centered:Boolean,lazyLoad:Boolean,currency:B("¥"),thumbLink:String,originPrice:b};var re=x({name:ae,props:ne,emits:["clickThumb"],setup(t,{slots:e,emit:u}){const l=()=>{if(e.title)return e.title();if(t.title)return a("div",{class:[n("title"),"van-multi-ellipsis--l2"]},[t.title])},r=()=>{if(e.tag||t.tag)return a("div",{class:n("tag")},[e.tag?e.tag():a(te,{mark:!0,type:"primary"},{default:()=>[t.tag]})])},d=()=>e.thumb?e.thumb():a(X,{src:t.thumb,fit:"cover",width:"100%",height:"100%",lazyLoad:t.lazyLoad},null),o=()=>{if(e.thumb||t.thumb)return a("a",{href:t.thumbLink,class:n("thumb"),onClick:c=>u("clickThumb",c)},[d(),r()])},m=()=>{if(e.desc)return e.desc();if(t.desc)return a("div",{class:[n("desc"),"van-ellipsis"]},[t.desc])},i=()=>{const c=t.price.toString().split(".");return a("div",null,[a("span",{class:n("price-currency")},[t.currency]),a("span",{class:n("price-integer")},[c[0]]),c.length>1&&a(I,null,[K("."),a("span",{class:n("price-decimal")},[c[1]])])])};return()=>{var c,v,s;const _=e.num||y(t.num),g=e.price||y(t.price),h=e["origin-price"]||y(t.originPrice),D=_||g||h||e.bottom,F=g&&a("div",{class:n("price")},[e.price?e.price():i()]),L=h&&a("div",{class:n("origin-price")},[e["origin-price"]?e["origin-price"]():`${t.currency} ${t.originPrice}`]),N=_&&a("div",{class:n("num")},[e.num?e.num():`x${t.num}`]),$=e.footer&&a("div",{class:n("footer")},[e.footer()]),z=D&&a("div",{class:n("bottom")},[(c=e["price-top"])==null?void 0:c.call(e),F,L,N,(v=e.bottom)==null?void 0:v.call(e)]);return a("div",{class:n()},[a("div",{class:n("header")},[o(),a("div",{class:n("content",{centered:t.centered})},[a("div",null,[l(),m(),(s=e.tags)==null?void 0:s.call(e)]),z])]),$])}}});const ce=w(re),oe=t=>q("/yuthon/yuthon/salary",{id:t}),ie={class:"container"},le={class:"header"},se={class:"salary-amount"},ue={class:"detail-section"},de={__name:"Salary",setup(t){const e=R({}),u=Q();return J(async()=>{const l=parseInt(u.query.id);try{const r=await oe(l);console.log(r),e.value=r.data}catch(r){H("获取工资条失败"),console.error(r)}}),(l,r)=>{const d=ce,o=j,m=O;return C(),S("div",ie,[f("div",le,k(e.value.date_from)+" - "+k(e.value.date_to)+" 工资条 ",1),a(d,{class:"salary-card",title:"实发工资",bordered:""},{desc:P(()=>[f("div",se,k(e.value.amount_total),1)]),_:1}),f("div",ue,[r[0]||(r[0]=f("div",{class:"section-title"},"明细",-1)),a(m,null,{default:P(()=>[(C(!0),S(I,null,U(e.value.lines_ids,i=>(C(),W(o,{key:i.name,title:i.name,value:i.total},null,8,["title","value"]))),128))]),_:1})])])}}},_e=M(de,[["__scopeId","data-v-4564b9eb"]]);export{_e as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{v as P,t as S,n as d,c as B,G as u,F as $,J as j,I as D,j as _}from"./requests-DdoUQiv8.js";import{d as C,r as f,v as F,c as N,w as R,f as U,o as G,n as z,g as n,x as J,y as M,m as b}from"./index-CimcMLIq.js";const[O,i]=B("image"),T={src:String,alt:String,fit:String,position:String,round:Boolean,block:Boolean,width:d,height:d,radius:d,lazyLoad:Boolean,iconSize:d,showError:S,errorIcon:P("photo-fail"),iconPrefix:String,showLoading:S,loadingIcon:P("photo"),crossorigin:String,referrerpolicy:String,decoding:String};var V=C({name:O,props:T,emits:["load","error"],setup(r,{emit:g,slots:c}){const t=f(!1),a=f(!0),o=f(),{$Lazyload:l}=F().proxy,x=N(()=>{const e={width:u(r.width),height:u(r.height)};return $(r.radius)&&(e.overflow="hidden",e.borderRadius=u(r.radius)),e});R(()=>r.src,()=>{t.value=!1,a.value=!0});const v=e=>{a.value&&(a.value=!1,g("load",e))},m=()=>{const e=new Event("load");Object.defineProperty(e,"target",{value:o.value,enumerable:!0}),v(e)},h=e=>{t.value=!0,a.value=!1,g("error",e)},y=(e,s,I)=>I?I():n(D,{name:e,size:r.iconSize,class:s,classPrefix:r.iconPrefix},null),E=()=>{if(a.value&&r.showLoading)return n("div",{class:i("loading")},[y(r.loadingIcon,i("loading-icon"),c.loading)]);if(t.value&&r.showError)return n("div",{class:i("error")},[y(r.errorIcon,i("error-icon"),c.error)])},k=()=>{if(t.value||!r.src)return;const e={alt:r.alt,class:i("img"),decoding:r.decoding,style:{objectFit:r.fit,objectPosition:r.position},crossorigin:r.crossorigin,referrerpolicy:r.referrerpolicy};return r.lazyLoad?J(n("img",b({ref:o},e),null),[[M("lazy"),r.src]]):n("img",b({ref:o,src:r.src,onLoad:v,onError:h},e),null)},w=({el:e})=>{const s=()=>{e===o.value&&a.value&&m()};o.value?s():z(s)},L=({el:e})=>{e===o.value&&!t.value&&h()};return l&&j&&(l.$on("loaded",w),l.$on("error",L),U(()=>{l.$off("loaded",w),l.$off("error",L)})),G(()=>{z(()=>{var e;(e=o.value)!=null&&e.complete&&!r.lazyLoad&&m()})}),()=>{var e;return n("div",{class:i({round:r.round,block:r.block}),style:x.value},[k(),E(),(e=c.default)==null?void 0:e.call(c)])}}});const H=_(V);export{H as I};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -35,29 +35,28 @@ class LeaveAllocationWizard(models.Model):
|
||||
holiday_status_id = self.env['hr.leave.type'].search([('name', '=', '年假'), ('company_id', '=', '天河物管')], limit=1)
|
||||
holiday_status_id1 = self.env['hr.leave.type'].search([('name', '=', '补休')], limit=1)
|
||||
accrual_plan_id = self.env['hr.leave.accrual.plan'].search([('name', '=', '年假(天河物管)')], limit=1)
|
||||
if row[1].value:
|
||||
number_of_days_display = int(row[1].value)/8
|
||||
else:
|
||||
number_of_days_display = 0
|
||||
self.env['hr.leave.allocation'].create({
|
||||
'employee_id': employee_id.id,
|
||||
'name': '年假公司分配',
|
||||
'number_of_days': number_of_days_display,
|
||||
'employee_ids': [(6, 0, [employee_id.id])],
|
||||
'holiday_status_id': holiday_status_id.id,
|
||||
'accrual_plan_id': accrual_plan_id.id,
|
||||
'allocation_type': 'accrual',
|
||||
"number_of_days_display":number_of_days_display,
|
||||
'notes':'年假公司分配'
|
||||
})
|
||||
self.env['hr.leave.allocation'].create({
|
||||
'employee_id': employee_id.id,
|
||||
'name': '补休',
|
||||
'employee_ids': [(6, 0, [employee_id.id])],
|
||||
'holiday_status_id' : holiday_status_id1.id,
|
||||
'number_of_hours_display':row[2].value,
|
||||
})
|
||||
|
||||
if row[1].value and int(row[1].value) != 0:
|
||||
number_of_days_display = int(row[1].value) / 8
|
||||
self.env['hr.leave.allocation'].create({
|
||||
'employee_id': employee_id.id,
|
||||
'name': '年假公司分配',
|
||||
'number_of_days': number_of_days_display,
|
||||
'employee_ids': [(6, 0, [employee_id.id])],
|
||||
'holiday_status_id': holiday_status_id.id,
|
||||
'accrual_plan_id': accrual_plan_id.id,
|
||||
'allocation_type': 'accrual',
|
||||
"number_of_days_display": number_of_days_display,
|
||||
'notes': '年假公司分配'
|
||||
})
|
||||
|
||||
if row[2].value and int(row[2].value) != 0:
|
||||
self.env['hr.leave.allocation'].create({
|
||||
'holiday_status_id': holiday_status_id1.id,
|
||||
'employee_id': employee_id.id,
|
||||
'name': '补休',
|
||||
'employee_ids': [(6, 0, [employee_id.id])],
|
||||
'number_of_hours_display': int(row[2].value)
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -82,15 +82,45 @@ class GoApprovals(models.Model):
|
||||
'approval_date': fields.Datetime.now(),
|
||||
})
|
||||
|
||||
@api.depends('users_id', 'days', 'hours')
|
||||
@api.depends('employee_ids', 'days', 'hours', 'statr_date', 'end_date', 'date_start', 'date_end', 'is_day', 'is_half',
|
||||
'is_hour')
|
||||
def _compute_name(self):
|
||||
for rec in self:
|
||||
if rec.is_hour == True:
|
||||
rec.name = f"{rec.users_id.name}外出{rec.hours}小时"
|
||||
elif rec.is_day == True:
|
||||
rec.name = f"{rec.users_id.name}外出{rec.days}天"
|
||||
employee_list = [employee.name for employee in rec.employee_ids]
|
||||
# 将员工列表转换为逗号分隔的字符串
|
||||
employees_str = ", ".join(employee_list)
|
||||
base_name = f"{employees_str}外出"
|
||||
date_info = ""
|
||||
if rec.is_hour:
|
||||
# 按小时
|
||||
if rec.date_start and rec.date_end:
|
||||
start_date = fields.Date.from_string(rec.date_start)
|
||||
end_date = fields.Date.from_string(rec.date_end)
|
||||
start_str = start_date.strftime('%Y-%m-%d')
|
||||
end_str = end_date.strftime('%Y-%m-%d')
|
||||
if start_date == end_date:
|
||||
date_info = f"{start_str}共:{rec.hours}小时"
|
||||
else:
|
||||
date_info = f"{start_str}至{end_str}共:{rec.hours}小时"
|
||||
|
||||
elif rec.is_day or rec.is_half:
|
||||
# 按天或半天
|
||||
if rec.statr_date and rec.end_date:
|
||||
start_str = rec.statr_date.strftime('%Y-%m-%d')
|
||||
end_str = rec.end_date.strftime('%Y-%m-%d')
|
||||
if rec.statr_date == rec.end_date:
|
||||
date_part = start_str
|
||||
else:
|
||||
date_part = f"{start_str}至{end_str}"
|
||||
if rec.is_day:
|
||||
date_info = f"{date_part}共:{rec.days}天"
|
||||
else:
|
||||
date_info = f"{date_part}共:{rec.days}天"
|
||||
|
||||
if date_info:
|
||||
rec.name = f"{base_name}{date_info}"
|
||||
else:
|
||||
rec.name = f"{rec.users_id.name}外出"
|
||||
rec.name = base_name
|
||||
|
||||
@api.onchange('statr_date', 'end_date')
|
||||
def _onchange_days(self):
|
||||
@@ -138,23 +168,68 @@ class GoApprovals(models.Model):
|
||||
def end_approval(self):
|
||||
if self.meal:
|
||||
# 创建日志
|
||||
go_approval_list = []
|
||||
first_day = self.statr_date.replace(day=1)
|
||||
reports_id = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', self.users_id.employee_id.id),
|
||||
('vacation_date', '=', first_day)
|
||||
])
|
||||
workflow_record_id = self.env['soong.workflow.record'].search([
|
||||
('code', '=', self.code)
|
||||
])
|
||||
go_approval_list.append((0, 0, {
|
||||
meal_fee_value = (0, 0, {
|
||||
'vacation_id': reports_id.id,
|
||||
'update_type': 'add',
|
||||
'workflow_record_id': workflow_record_id.id,
|
||||
'update_date': fields.Datetime.now(),
|
||||
'update_lines': 1 ,
|
||||
'update_lines': 1,
|
||||
'text': '审批'
|
||||
}))
|
||||
reports_id.write({'meal_fee_ids': [(0, 0, go_approval_list)]})
|
||||
|
||||
})
|
||||
reports_id.write({'meal_fee_ids': [meal_fee_value]})
|
||||
|
||||
for employee in self.employee_ids:
|
||||
if self.is_day or self.is_half:
|
||||
start = self.statr_date
|
||||
end = self.end_date
|
||||
date_field = 'current_data'
|
||||
elif self.is_hour:
|
||||
start = self.date_start.date() if self.date_start else None
|
||||
end = self.date_end.date() if self.date_end else None
|
||||
date_field = 'current_data'
|
||||
else:
|
||||
return True
|
||||
if not (start and end):
|
||||
return True
|
||||
attendance_records = self.env['hr.attendance'].search([
|
||||
('employee_id', '=', employee.id),
|
||||
(date_field, '>=', start),
|
||||
(date_field, '<=', end)
|
||||
])
|
||||
if attendance_records:
|
||||
attendance_records.write({
|
||||
'is_clock_card': True,
|
||||
'is_no_card': False,
|
||||
'is_early_card': False,
|
||||
'is_late_card': False,
|
||||
'is_abnormal': False,
|
||||
'absenteeism_card': False
|
||||
})
|
||||
else:
|
||||
current_date = start
|
||||
while current_date <= end:
|
||||
self.env['hr.attendance'].create({
|
||||
'employee_id': employee.id,
|
||||
date_field: current_date,
|
||||
'is_clock_card': True,
|
||||
'check_in': False,
|
||||
'check_out': False,
|
||||
'is_no_card': False,
|
||||
'is_early_card': False,
|
||||
'is_late_card': False,
|
||||
'is_abnormal': False,
|
||||
'absenteeism_card': False
|
||||
})
|
||||
# 日期递增
|
||||
current_date += timedelta(days=1)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ class HrAttendance(models.Model):
|
||||
if record.absenteeism_card:
|
||||
absenteeism_card += 1
|
||||
if has_abnormal:
|
||||
url = f"http://oa.thtzjt.com/#/clock_in_staticstis?user_id={employee.user_id.id}"
|
||||
url = f"https://oa.thtzjt.com/webh5#/clock_in_staticstis?user_id={employee.user_id.id}"
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='att', user_id=employee.wecom_userid, title="打卡异常提醒",
|
||||
description="本月迟到: {}\n本月缺卡: {}\n本月早退: {}\n本月异常:{}\n 本月旷工: {}\n"
|
||||
.format(is_late_card, is_no_card, is_early_card, is_abnormal, absenteeism_card),
|
||||
@@ -264,7 +264,7 @@ class HrAttendance(models.Model):
|
||||
# 工作日打卡情况判断
|
||||
if is_workday:
|
||||
if employee_record:
|
||||
is_no_card = not employee_record.check_in or not employee_record.check_out
|
||||
is_no_card = (not employee_record.check_in or not employee_record.check_out) and not employee_record.is_clock_card
|
||||
else:
|
||||
is_no_card = True
|
||||
else:
|
||||
@@ -1044,6 +1044,13 @@ class HrAttendance(models.Model):
|
||||
self._update_vacation_report(record)
|
||||
return result
|
||||
|
||||
def unlink(self):
|
||||
for record in self:
|
||||
self._update_vacation_report(record)
|
||||
result = super(HrAttendance, self).unlink()
|
||||
return result
|
||||
|
||||
|
||||
def _update_vacation_report(self, record):
|
||||
"""更新相关的假期报表日志"""
|
||||
if record.current_data and record.employee_id:
|
||||
|
||||
@@ -110,7 +110,9 @@ class HrAttendanceDetail(models.Model):
|
||||
for resource_id in role.resource_ids:
|
||||
employee_list.append(resource_id.employee_id.id)
|
||||
if not record.employee_id.id in employee_list:
|
||||
days = self.env['yuthon.vacation.reports']._create_leave_record(slot_start_dt, slot_end_dt)
|
||||
start_dt = slot_start_dt.date()
|
||||
end_dt = slot_end_dt.date()
|
||||
days = self.env['yuthon.vacation.reports']._create_leave_record(record.employee_id, start_dt, end_dt)
|
||||
else:
|
||||
monthly_slots = self.env['planning.slot'].search([
|
||||
('employee_id', '=', record.employee_id.id),
|
||||
@@ -509,6 +511,7 @@ class HrAttendanceDetail(models.Model):
|
||||
result = response.json()
|
||||
if result.get('errcode') != 0:
|
||||
# 301021至少有一个不存在通讯录
|
||||
# 301024获取打卡间隔受限
|
||||
_logger.error('获取外出打卡数据失败\n异常:{0}\n数量:{1}\n用户列表:{2}'.format(str(result.get('errmsg')), len(userid_limit), str(userid_limit)))
|
||||
return []
|
||||
checkin_data = result.get('checkindata', [])
|
||||
@@ -621,11 +624,14 @@ class HrAttendanceDetail(models.Model):
|
||||
"""
|
||||
# 从用户列表里获取企业微信的用户
|
||||
user_list = self._get_wx_attendance_user_list()
|
||||
now_time = datetime.now() + timedelta(hours=8)
|
||||
start_time = now_time - timedelta(days=30)
|
||||
now_time = datetime(2025, 9, 1) # 替换为你需要的年份
|
||||
start_time = datetime(2025, 8, 15) # 替换为你需要的年份
|
||||
# now_time = datetime.now() + timedelta(hours=8)
|
||||
# start_time = now_time - timedelta(days=3)
|
||||
|
||||
# 企业微信获取打卡数据,要求用户分组100,分批获取打卡记录
|
||||
# for userid_limit in self.utils_list_page(user_list, 1):
|
||||
|
||||
for userid_limit in user_list:
|
||||
# 获取企业微信的打卡信息
|
||||
try:
|
||||
|
||||
@@ -180,6 +180,7 @@ class OvertimeApprovals(models.Model):
|
||||
if self.meal == 'yes':
|
||||
meal_number += 1
|
||||
employee_id.write({'meal_number': meal_number})
|
||||
|
||||
holiday_status_id = self.env['hr.leave.type'].search([('name', '=', '补休')])
|
||||
allocation = self.env['hr.leave.allocation'].create({
|
||||
'employee_id': employee_id.id,
|
||||
@@ -224,6 +225,17 @@ class OvertimeApprovals(models.Model):
|
||||
'update_date': fields.Datetime.now(),
|
||||
'text': '审批'
|
||||
}
|
||||
if self.meal == 'yes':
|
||||
meal_fee_value = (0, 0, {
|
||||
'vacation_id': reports_id.id,
|
||||
'update_type': 'add',
|
||||
'workflow_record_id': workflow_record_id.id,
|
||||
'update_date': fields.Datetime.now(),
|
||||
'update_lines': 1,
|
||||
'text': '审批'
|
||||
})
|
||||
reports_id.write({'meal_fee_ids': [meal_fee_value]})
|
||||
|
||||
reports_id.write({'overtime_ids': [(0, 0, overtime_data)]})
|
||||
|
||||
@api.depends('users_id', 'duration')
|
||||
|
||||
@@ -13,6 +13,7 @@ class WifiMessage(models.Model):
|
||||
mac = fields.Char(string='MAC地址')
|
||||
name = fields.Char(string='详细地址')
|
||||
bssid = fields.Char(string='BSSID')
|
||||
create_time = fields.Date(string='创建日期', default=lambda self: fields.Date.today())
|
||||
company_id = fields.Many2one("res.company", string="公司", default=lambda self: self.env.company)
|
||||
|
||||
|
||||
|
||||
@@ -22,13 +22,13 @@ class YuthonVacationReports(models.Model):
|
||||
meal_fee_ids = fields.One2many('vacation.meal.line', 'vacation_id', string='误餐明细')
|
||||
medical_fee_ids = fields.One2many('vacation.medical.line', 'vacation_id', string='体检费明细')
|
||||
other_fee_ids = fields.One2many('vacation.other.line', 'vacation_id', string='其他明细')
|
||||
vacation_date = fields.Date(string='日期', default=lambda self: fields.Date.today())
|
||||
vacation_date = fields.Date(string='日期', default=lambda self: fields.Date.today().replace(day=1))
|
||||
display_date = fields.Char(string='日期', compute='_compute_display_date')
|
||||
done_leave = fields.Float(string='年假', compute='_compute_leave', store=True, digits=(16, 3), group_operator=None)
|
||||
done_working_overtime = fields.Float(string='加班时', compute='_compute_working_overtime', digits=(16, 3),
|
||||
store=True, group_operator=None)
|
||||
leave = fields.Float(string='剩余年假', compute='_compute_leave', store=True, digits=(16, 3), group_operator=None)
|
||||
working_overtime = fields.Float(string='剩余加班时', compute='_compute_working_overtime', store=True,
|
||||
working_overtime = fields.Float(string='剩余补休', compute='_compute_working_overtime', store=True,
|
||||
digits=(16, 3), group_operator=None)
|
||||
meal_fee = fields.Integer(string="误餐次数", compute='_compute_meal_fee', store=True, group_operator=None)
|
||||
medical_fee = fields.Float(string="体检费", compute='_compute_medical_fee', store=True, group_operator=None)
|
||||
@@ -36,7 +36,7 @@ class YuthonVacationReports(models.Model):
|
||||
leave_of_absence = fields.Float(string="事假", digits=(16, 3), compute='_compute_other_leave', store=True,
|
||||
group_operator=None)
|
||||
statutory_leave = fields.Integer(string="加班时(法定)", compute='_compute_other_leave', store=True, group_operator=None)
|
||||
cop_leave = fields.Float(string='补休', digits=(16, 3), compute='_compute_other_leave', store=True,
|
||||
cop_leave = fields.Float(string='补休', digits=(16, 3), store=True, compute='_compute_working_overtime',
|
||||
group_operator=None)
|
||||
duty_off_leave = fields.Integer(string='值班调休', compute='_compute_other_leave', store=True, group_operator=None)
|
||||
marriage_leave = fields.Integer(string='婚假', compute='_compute_other_leave', store=True, group_operator=None)
|
||||
@@ -73,6 +73,21 @@ class YuthonVacationReports(models.Model):
|
||||
tracking=3,
|
||||
default='unconfirmed')
|
||||
|
||||
@api.constrains('employee_id', 'vacation_date')
|
||||
def _check_duplicate_monthly_record(self):
|
||||
"""检查是否存在同一员工当月的重复记录"""
|
||||
for record in self:
|
||||
duplicate_records = self.search([
|
||||
('employee_id', '=', record.employee_id.id),
|
||||
('vacation_date', '=', record.vacation_date),
|
||||
('id', '!=', record.id)
|
||||
])
|
||||
if duplicate_records:
|
||||
raise ValidationError(
|
||||
f"员工 {record.employee_id.name} 在 {record.vacation_date.strftime('%Y年%m月')} "
|
||||
f"已存在假期额度记录,不能重复创建!"
|
||||
)
|
||||
|
||||
def confirm_state(self):
|
||||
for rec in self:
|
||||
rec.vacation_state = 'confirmed'
|
||||
@@ -131,8 +146,16 @@ class YuthonVacationReports(models.Model):
|
||||
days_in_month = calendar.monthrange(year, month)[1]
|
||||
month_start = date(year, month, 1)
|
||||
month_end = date(year, month, days_in_month)
|
||||
leave_days = rec._create_leave_record(month_start, month_end)
|
||||
for day in range(1, days_in_month + 1):
|
||||
leave_days = rec._create_leave_record(rec.employee_id, month_start, month_end)
|
||||
entry_date = rec.employee_id.entry_date
|
||||
if month_start > entry_date:
|
||||
start_day = 1
|
||||
else:
|
||||
days_in_month = (date(year, month + 1, 1) - timedelta(days=1)).day
|
||||
start_day = min(entry_date.day, days_in_month)
|
||||
days_in_month = (date(year, month + 1, 1) - timedelta(days=1)).day
|
||||
actual_days_range = range(start_day, days_in_month + 1)
|
||||
for day in actual_days_range:
|
||||
current_date = date(year, month, day)
|
||||
attendances = self.env["hr.attendance"].sudo().search([
|
||||
('employee_id', '=', rec.employee_id.id),
|
||||
@@ -172,8 +195,8 @@ class YuthonVacationReports(models.Model):
|
||||
rec._compute_attendance_fields1()
|
||||
|
||||
def update_data(self):
|
||||
august_start = fields.Date.from_string('2025-08-01')
|
||||
august_end = fields.Date.from_string('2025-08-31')
|
||||
august_start = fields.Date.from_string('2025-09-01')
|
||||
august_end = fields.Date.from_string('2025-9-30')
|
||||
august_records = self.env["yuthon.vacation.reports"].search([
|
||||
('vacation_date', '>=', august_start),
|
||||
('vacation_date', '<=', august_end)
|
||||
@@ -228,7 +251,10 @@ class YuthonVacationReports(models.Model):
|
||||
for field in int_fields:
|
||||
setattr(rec, field, getattr(rec, field) or 0)
|
||||
|
||||
def _create_leave_record(self, start_date, end_date):
|
||||
def _create_leave_record(self, employee_id, start_date, end_date):
|
||||
entry_date = employee_id.entry_date
|
||||
# 调整日期范围:如果开始日期早于入职日期,则从入职日期开始计算
|
||||
actual_start_date = max(start_date, entry_date) if entry_date else start_date
|
||||
calendar_leaves = self.env['resource.calendar.leaves'].search([("calendar_id", "=", "行政考勤工作日")])
|
||||
holidays_list = []
|
||||
shift_days_list = []
|
||||
@@ -243,7 +269,7 @@ class YuthonVacationReports(models.Model):
|
||||
holidays_list = [self.remove_leading_zero(date) for date in holidays_list]
|
||||
shift_days_list = [self.remove_leading_zero(date) for date in shift_days_list]
|
||||
days = 0 # 初始化工作日计数
|
||||
current_date = start_date
|
||||
current_date = actual_start_date
|
||||
|
||||
while current_date <= end_date:
|
||||
current_date_str = current_date.strftime('%m月%d日')
|
||||
@@ -476,25 +502,33 @@ class YuthonVacationReports(models.Model):
|
||||
'overtime_ids.legal_day',
|
||||
'overtime_ids.public_holidays',
|
||||
'overtime_ids.update_type',
|
||||
'overtime_ids.is_void'
|
||||
'overtime_ids.is_void',
|
||||
'overtime_ids.workflow_record_id'
|
||||
)
|
||||
def _compute_working_overtime(self):
|
||||
for record in self:
|
||||
total_add1 = 0.0
|
||||
total_add2 = 0.0
|
||||
total_add = 0.0
|
||||
total_reduce = 0.0
|
||||
done_working_overtime = 0.0
|
||||
|
||||
for line in record.overtime_ids:
|
||||
if not line.is_void:
|
||||
line_total = (line.workday or 0) + (line.legal_day or 0) + (line.public_holidays or 0)
|
||||
if line.update_type == 'add':
|
||||
total_add += line_total
|
||||
elif line.update_type == 'reduce':
|
||||
total_reduce += line_total
|
||||
total_add -= line_total
|
||||
done_working_overtime += line_total
|
||||
if line.is_void:
|
||||
continue
|
||||
|
||||
line_total = (line.workday or 0) + (line.legal_day or 0) + (line.public_holidays or 0)
|
||||
if line.update_type == 'add':
|
||||
total_add += line_total
|
||||
elif line.update_type == 'reduce':
|
||||
total_add -= line_total
|
||||
|
||||
if line.workflow_record_id and line.update_type == 'add':
|
||||
total_add1 += line_total
|
||||
if line.workflow_record_id and line.update_type == 'reduce':
|
||||
total_add2 += line_total
|
||||
|
||||
record.working_overtime = max(total_add / 8, 0)
|
||||
record.done_working_overtime = done_working_overtime / 8
|
||||
record.cop_leave = total_reduce / 8
|
||||
record.done_working_overtime = total_add1 / 8
|
||||
record.cop_leave = total_add2 / 8
|
||||
|
||||
@api.depends('meal_fee_ids.update_lines', 'meal_fee_ids.update_type', 'meal_fee_ids.is_void')
|
||||
def _compute_meal_fee(self):
|
||||
@@ -738,9 +772,9 @@ class VacationMealLine(models.Model):
|
||||
delta = int(record.update_lines) * sign
|
||||
|
||||
if record.update_type == 'add':
|
||||
employee.write({'meal_count': employee.meal_count + delta})
|
||||
employee.write({'meal_number': employee.meal_number + delta})
|
||||
elif record.update_type == 'reduce':
|
||||
employee.write({'meal_count': employee.meal_count - delta})
|
||||
employee.write({'meal_number': employee.meal_number - delta})
|
||||
|
||||
def unlink(self):
|
||||
self._sync_to_employee(reverse=True)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<field name="domain_force">[('company_id', 'in', company_ids)]</field>
|
||||
</record>
|
||||
<record id="module_he_attendance_sign" model="ir.module.category">
|
||||
<field name="name">考勤记录详情组</field>
|
||||
<field name="name">考勤记录详情/修正组</field>
|
||||
</record>
|
||||
<record id="group_he_attendance_sign_manager" model="res.groups">
|
||||
<field name="name">管理员</field>
|
||||
|
||||
@@ -9,10 +9,16 @@
|
||||
decoration-danger="is_workflow or is_approval"
|
||||
editable="bottom">
|
||||
<header>
|
||||
<button name="compute_company_id" string="公司更新" type="object" class="btn btn-primary"/>
|
||||
<!-- <button name="compute_company_id" string="公司更新" type="object" class="btn btn-primary"/>-->
|
||||
<!-- <button name="button_all" string="班次更新" type="object" class="btn btn-primary"/>-->
|
||||
<button name="compute_attendance_ids" string="重新计算" type="object" class="btn btn-primary"/>
|
||||
<button name="state_fix" string="状态修正" type="object" class="btn btn-primary" groups="yuthon_hr_attendance.group_he_attendance_sign_manager"/>
|
||||
<button name="unlink"
|
||||
string="删除"
|
||||
type="object"
|
||||
icon="fa-trash"
|
||||
groups="yuthon_hr_attendance.group_he_attendance_sign_manager"
|
||||
confirm="确定要删除选中的记录吗?"/>
|
||||
</header>
|
||||
<field name="employee_id" class="list_current_data" options="{'no_create': True}"/>
|
||||
<field name="current_data" optional="show" class="list_current_data"/>
|
||||
@@ -39,8 +45,8 @@
|
||||
<field name="is_workflow" optional="hidden"/>
|
||||
<field name="workflow_id" optional="hidden"/>
|
||||
<button name="button_controls_wizard" type="object" string="操作" class="oe_highlight" invisible="not (is_abnormal or is_early_card or is_late_card or absenteeism_card or is_no_card)"/>
|
||||
<button name="button_correct_wizard" type="object" string="修正" class="btn btn-primary" invisible="not (is_abnormal or is_early_card or is_late_card or absenteeism_card or is_no_card)" groups="base.group_system"/>
|
||||
<button name="revoke" type="object" string="撤销" class="btn btn-primary" invisible="not (is_check_out_red or is_check_in_red)" groups="base.group_system"/>
|
||||
<button name="button_correct_wizard" type="object" string="修正" class="btn btn-primary" invisible="not (is_abnormal or is_early_card or is_late_card or absenteeism_card or is_no_card)" groups="yuthon_hr_attendance.group_he_attendance_sign_manager"/>
|
||||
<button name="revoke" type="object" string="撤销" class="btn btn-primary" invisible="not (is_check_out_red or is_check_in_red)" groups="yuthon_hr_attendance.group_he_attendance_sign_manager"/>
|
||||
<button name="button_workflow" type="object" string="流程" class="oe_highlight" invisible="not is_workflow"/>
|
||||
<button name="button_source" type="object" string="详情" class="oe_highlight" groups="yuthon_hr_attendance.group_he_attendance_sign_manager"/>
|
||||
</tree>
|
||||
@@ -80,8 +86,8 @@
|
||||
<field name="is_check_in_red" column_invisible="1"/>
|
||||
<field name="is_check_out_red" column_invisible="1"/>
|
||||
<button name="button_controls_wizard" type="object" string="操作" class="oe_highlight" invisible="not (is_abnormal or is_early_card or is_late_card or absenteeism_card or is_no_card)"/>
|
||||
<button name="button_correct_wizard" type="object" string="修正" class="btn btn-primary" invisible="not (is_abnormal or is_early_card or is_late_card or absenteeism_card or is_no_card)" groups="base.group_system"/>
|
||||
<button name="revoke" type="object" string="撤销" class="btn btn-primary" invisible="not (is_check_out_red or is_check_in_red)" groups="base.group_system"/>
|
||||
<button name="button_correct_wizard" type="object" string="修正" class="btn btn-primary" invisible="not (is_abnormal or is_early_card or is_late_card or absenteeism_card or is_no_card)" groups="yuthon_hr_attendance.group_he_attendance_sign_manager"/>
|
||||
<button name="revoke" type="object" string="撤销" class="btn btn-primary" invisible="not (is_check_out_red or is_check_in_red)" groups="yuthon_hr_attendance.group_he_attendance_sign_manager"/>
|
||||
<button name="button_source" type="object" string="详情" class="oe_highlight" groups="yuthon_hr_attendance.group_he_attendance_sign_manager"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -157,14 +163,14 @@
|
||||
<field name="binding_model_id" ref="yuthon_hr_attendance.model_hr_attendance"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.button_batch_correct()</field>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_system'))]"/>
|
||||
<field name="groups_id" eval="[(4, ref('yuthon_hr_attendance.group_he_attendance_sign_manager'))]"/>
|
||||
</record>
|
||||
<record id="action_update_shift" model="ir.actions.server">
|
||||
<field name="name">批量更新班次</field>
|
||||
<field name="model_id" ref="yuthon_hr_attendance.model_hr_attendance"/>
|
||||
<field name="binding_model_id" ref="yuthon_hr_attendance.model_hr_attendance"/>
|
||||
<field name="state">code</field>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_system'))]"/>
|
||||
<field name="groups_id" eval="[(4, ref('yuthon_hr_attendance.group_he_attendance_sign_manager'))]"/>
|
||||
</record>
|
||||
<record id="action_update_abnormal_shift" model="ir.actions.server">
|
||||
<field name="name">批量更新异常</field>
|
||||
@@ -172,6 +178,6 @@
|
||||
<field name="binding_model_id" ref="yuthon_hr_attendance.model_hr_attendance"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.update_abnormal()</field>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_system'))]"/>
|
||||
<field name="groups_id" eval="[(4, ref('yuthon_hr_attendance.group_he_attendance_sign_manager'))]"/>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<field name="name"/>
|
||||
<field name="bssid" />
|
||||
<field name="company_id"/>
|
||||
<field name="create_time"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -99,7 +99,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="假期额度日志">
|
||||
<sheet>
|
||||
<field name="employee_id" invisible="1"/>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<field name="employee_id"/>
|
||||
<field name="vacation_date"/>
|
||||
<div class="col-12 text-center">
|
||||
<h1>
|
||||
<field name="display_date"/>
|
||||
@@ -194,7 +198,7 @@
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="其他">
|
||||
<page string="请假情况">
|
||||
<field name="other_fee_ids" context="{'default_employee_id': employee_id}">
|
||||
<tree editable="bottom" delete="false" decoration-muted="is_void">
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
|
||||
@@ -130,6 +130,11 @@ class YuthonMessageLogin(models.Model):
|
||||
degree_id_ids = fields.One2many('education.details.line2', 'degree_id', string="学位证")
|
||||
certificate_ids = fields.One2many('certificates.detail.line', 'certificate_id', string="专业证书")
|
||||
|
||||
@api.onchange('staff_name')
|
||||
def _onchange_staff_name(self):
|
||||
if self.staff_name:
|
||||
self.name = '人员信息登记表'+ '-' + self.staff_name
|
||||
|
||||
@api.onchange('is_issues')
|
||||
def _onchange_is_issues(self):
|
||||
if self.is_issues:
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
parent="hr_process_work_job"
|
||||
action="yuthon_recruitment_approval_action"
|
||||
sequence="1"/>
|
||||
<menuitem id="hr_menu_message_login"
|
||||
name="个人信息登记表"
|
||||
parent="hr_process_work_job"
|
||||
action="yuthon_message_login_action"
|
||||
sequence="2"/>
|
||||
<menuitem id="hr_menu_interview_approval"
|
||||
name="面试信息表"
|
||||
parent="hr_process_work_job"
|
||||
@@ -22,11 +27,6 @@
|
||||
parent="hr_process_work_job"
|
||||
action="yuthon_onboard_approval_action"
|
||||
sequence="5"/>
|
||||
<menuitem id="hr_menu_message_login"
|
||||
name="个人信息登记表"
|
||||
parent="hr_process_work_job"
|
||||
action="yuthon_message_login_action"
|
||||
sequence="7"/>
|
||||
<menuitem id="hr_menu_prepare_approval"
|
||||
name="编制调整申请表"
|
||||
parent="hr_process_work_job"
|
||||
|
||||
@@ -51,6 +51,7 @@ class YuthonProperty(models.Model):
|
||||
image_1920 = fields.Image(string="图片")
|
||||
description = fields.Html(string="描述")
|
||||
is_message_fee = fields.Boolean(string="管理费")
|
||||
financial_address = fields.Char(string="财务地址")
|
||||
message_standard_id = fields.Many2one('property.message.fee', string="管理费标准")
|
||||
rental_unit_price = fields.Float(string="评估单价")
|
||||
title_number = fields.Char(string="产权编号")
|
||||
|
||||
Binary file not shown.
@@ -71,6 +71,7 @@
|
||||
<field name="units"/>
|
||||
<field name="property_orientation"/>
|
||||
<field name="street"/>
|
||||
<field name="financial_address"/>
|
||||
<field name="effective_date"/>
|
||||
</group>
|
||||
<group>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<record id="initialize_template_downloads_action" model="ir.actions.act_url">
|
||||
<field name="name">初始化模板下载</field>
|
||||
<field name="target">self</field>
|
||||
<field name="url">.</field>
|
||||
<field name="url">/yuthon_property/static/others/rent_temp.xlsx</field>
|
||||
</record>
|
||||
<record id="initialize_wizard_form" model="ir.ui.view">
|
||||
<field name="name">审批意见弹窗</field>
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
'views/property_accounting_approval_views.xml',
|
||||
'views/property_record_views.xml',
|
||||
'views/property_equity_views.xml',
|
||||
'views/payment_process_viwes.xml',
|
||||
'views/property_handover_views.xml',
|
||||
'views/property_merge_approval_views.xml',
|
||||
'views/property_current_approval_views.xml',
|
||||
@@ -80,6 +81,7 @@
|
||||
'wizard/binding_information_wizard_views.xml',
|
||||
'wizard/property_rental_wizard_views.xml',
|
||||
'wizard/contract_signature_wizard_viwes.xml',
|
||||
'wizard/build_pop_wizard_viwes.xml',
|
||||
'wizard/property_meeting_wizard_views.xml',
|
||||
'views/property_menu_all.xml',
|
||||
],
|
||||
|
||||
@@ -7,7 +7,13 @@
|
||||
<field name="padding">3</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="payment_process_code_sequence" model="ir.sequence">
|
||||
<field name="name">支付流程编号</field>
|
||||
<field name="code">payment_process_code</field>
|
||||
<field name="prefix">ZF%(y)s%(month)s%(day)s</field>
|
||||
<field name="padding">3</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
<record id="property_business_confirm_code_sequence" model="ir.sequence">
|
||||
<field name="name">经营报表确认单编号</field>
|
||||
<field name="code">property_business_confirm_code</field>
|
||||
|
||||
@@ -55,4 +55,5 @@ from . import property_accounts_approval
|
||||
from . import inherit_property_tenant_information
|
||||
from . import property_meeting_approval
|
||||
from . import property_lessee_analysis
|
||||
from . import yuthon_property_ledger
|
||||
from . import yuthon_property_ledger
|
||||
from . import payment_process
|
||||
@@ -0,0 +1,32 @@
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class PaymentProcess(models.Model):
|
||||
_name = 'payment.process'
|
||||
_description = '支付流程'
|
||||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||||
|
||||
|
||||
code = fields.Char(string="编号", readonly=True,default=lambda self: self.env['ir.sequence'].next_by_code('payment_process_code'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one(related='users_id.employee_id.company_id', string="公司")
|
||||
supervising_id = fields.Many2one('property.supervising.approval', string='合同编号')
|
||||
reason = fields.Text(related='supervising_id.reason', string='事项')
|
||||
payment_instructions = fields.Text(string='支付说明')
|
||||
payment_nodes = fields.Selection([('first', '一期'), ('second', '二期'), ('third', '三期'), ('fourth', '四期')],
|
||||
string="支付节点")
|
||||
amount = fields.Float(string="金额")
|
||||
documents_id = fields.Many2one('ir.attachment', string="附件")
|
||||
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
active = fields.Boolean('Active', default=True, tracking=True)
|
||||
work_end = fields.Boolean(string="结束")
|
||||
|
||||
def _get_default_name_title(self):
|
||||
return self._description if self._description else self._name
|
||||
|
||||
name_title = fields.Char(default=_get_default_name_title)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人",
|
||||
default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
@@ -7,28 +7,29 @@ from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
class PropertyAccountingApproval(models.Model):
|
||||
_name = 'property.accounting.approval'
|
||||
_description = '建设工程委托核算合同审批'
|
||||
_description = '建设工程委托监理合同审批 '
|
||||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||||
|
||||
name = fields.Char(string='标题')
|
||||
name = fields.Char(string='合同编号')
|
||||
code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('property_accounting_approval_code'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
project_content = fields.Char(string="工程内容")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
property_id = fields.Many2one('yuthon.property', string='物业')
|
||||
company_id = fields.Many2one(related='users_id.employee_id.company_id', string="公司")
|
||||
company_a_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
reason = fields.Text(string="正文")
|
||||
three_point_offer = fields.Text(string="三方报价")
|
||||
documents_ids = fields.Many2many('ir.attachment', string="附件")
|
||||
contract_id = fields.Many2one('ir.attachment', string="合同")
|
||||
budget_list_id = fields.Many2one('ir.attachment', string="预算清单")
|
||||
project_content = fields.Char(string="工程内容")
|
||||
image = fields.Binary(string="维修前图片")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
property_address = fields.Char(string='物业地址')
|
||||
contract_amount = fields.Float(string="合同金额")
|
||||
start_date = fields.Date(string="开始日期")
|
||||
end_date = fields.Date(string="结束日期")
|
||||
amount = fields.Float(string="总金额")
|
||||
is_tex = fields.Boolean(string="是否含税")
|
||||
lack = fields.Float(string="差额")
|
||||
percentage = fields.Float(string="差额百分比")
|
||||
business_type = fields.Char(string="业务类型")
|
||||
payment_methods = fields.Selection([('onetime', '一次性'), ('installment', '分期')], string="付款方式")
|
||||
contract_id = fields.Many2one('ir.attachment', string="合同")
|
||||
accounting_way_ids = fields.One2many('accounting.way.line', 'accounting_id', string="关联支付方式明细行")
|
||||
lease_ids = fields.One2many('property.lease.contract.line', 'accounting_id', string="物业信息明细")
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
active = fields.Boolean('Active', default=True, tracking=True)
|
||||
@@ -40,12 +41,26 @@ class PropertyAccountingApproval(models.Model):
|
||||
name_title = fields.Char(default=_get_default_name_title)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
|
||||
def build_pop(self):
|
||||
return {
|
||||
'name': '添加物业',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'build.pop.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_accounting_id': self.id,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class AccountingWayLine(models.Model):
|
||||
_name = 'accounting.way.line'
|
||||
|
||||
pay_way = fields.Selection([('cumulative', '累计项'), ('stage', '单项'), ('other', '其他')], string="付款方式",)
|
||||
interval = fields.Char(string="区间")
|
||||
service_charge = fields.Float(string="服务费")
|
||||
payment_nodes = fields.Selection([('first', '一期'), ('second', '二期'), ('third', '三期'), ('fourth', '四期')],
|
||||
string="支付节点")
|
||||
payout_ratio = fields.Float(string="支付比例")
|
||||
amount = fields.Float(string="金额")
|
||||
remake = fields.Char(string="备注")
|
||||
payment_instructions = fields.Text(string="支付说明")
|
||||
accounting_id = fields.Many2one('property.accounting.approval', string="关联核算方式")
|
||||
|
||||
@@ -7,27 +7,29 @@ from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
class PropertyConstructionApproval(models.Model):
|
||||
_name = 'property.construction.approval'
|
||||
_description = '建设工程施工合同审批'
|
||||
_description = '建设工程造价咨询合同审批'
|
||||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||||
|
||||
name = fields.Char(string='标题')
|
||||
code = fields.Char(string="编号",
|
||||
default=lambda self: self.env['ir.sequence'].next_by_code('property_construction_approval_code'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
user_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='user_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one(related='user_id.employee_id.company_id', string="公司")
|
||||
company_a_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
project_content = fields.Char(string="工程内容")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
property_id = fields.Many2one('yuthon.property', string='物业')
|
||||
property_address = fields.Char(string='物业地址')
|
||||
reason = fields.Text(string="正文")
|
||||
image = fields.Binary(string="开工前图片")
|
||||
contract_id = fields.Many2one('ir.attachment', string="合同")
|
||||
start_date = fields.Date(string="开始日期")
|
||||
end_date = fields.Date(string="结束日期")
|
||||
review_price = fields.Float(string="审核价")
|
||||
budget_list_id = fields.Many2one('ir.attachment', string="预算清单")
|
||||
start_date = fields.Date(string="代理开始日期")
|
||||
end_date = fields.Date(string="代理结束日期")
|
||||
business_type = fields.Char(string="业务类型")
|
||||
contract_amount = fields.Float(string="合同金额")
|
||||
payment_methods = fields.Char(string="付款方式")
|
||||
contract_id = fields.Many2one('ir.attachment', string="合同")
|
||||
payment_methods = fields.Selection([('onetime', '一次性'), ('installment', '分期')], string="付款方式")
|
||||
lease_ids = fields.One2many('property.lease.contract.line', 'construction_id', string="物业信息明细")
|
||||
construction_way_ids = fields.One2many('construction.way.line', 'construction_id', string="关联支付方式")
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
@@ -40,15 +42,28 @@ class PropertyConstructionApproval(models.Model):
|
||||
name_title = fields.Char(default=_get_default_name_title)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
|
||||
def build_pop(self):
|
||||
return {
|
||||
'name': '添加物业',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'build.pop.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_construction_id': self.id,
|
||||
}
|
||||
}
|
||||
|
||||
class ConstructionWayLine(models.Model):
|
||||
_name = 'construction.way.line'
|
||||
_description = '施工支付方式'
|
||||
_description = '价咨询合同审批支付方式'
|
||||
|
||||
name = fields.Char(string="支付节点")
|
||||
pay_ratio = fields.Float(string="支付比例%")
|
||||
payment_nodes = fields.Selection([('first', '一期'), ('second', '二期'), ('third', '三期'), ('fourth', '四期')],
|
||||
string="支付节点")
|
||||
payout_ratio = fields.Float(string="支付比例")
|
||||
coping_date = fields.Date(string="应付日期")
|
||||
amount = fields.Float(string="金额")
|
||||
paid_time = fields.Text(string="付费时间")
|
||||
remake = fields.Char(string="备注")
|
||||
construction_id = fields.Many2one('property.construction.approval', string="关联施工合同")
|
||||
payment_instructions = fields.Text(string="支付说明")
|
||||
construction_id = fields.Many2one('property.construction.approval', string="关联价咨询合同审批")
|
||||
|
||||
|
||||
@@ -6,19 +6,27 @@ from odoo import models, fields, api, exceptions, _
|
||||
|
||||
class PropertyDelegatedAgent(models.Model):
|
||||
_name = 'property.delegated.agent'
|
||||
_description = '零星工程'
|
||||
_description = '零星工程年度委托合同审批'
|
||||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||||
|
||||
name = fields.Char(string="名称")
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
name = fields.Char(string="合同编号")
|
||||
department_id = fields.Many2one(related='user_id.employee_id.department_id', string="部门")
|
||||
code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('property_delegated_agent_code'))
|
||||
annual = fields.Char(string="年度")
|
||||
contract_date = fields.Date(string="合同有效期")
|
||||
signing_date = fields.Date(string="签订日期")
|
||||
payment_date = fields.Date(string="付款日期")
|
||||
consult_fee = fields.Float(string="咨询费")
|
||||
quotations_list_id = fields.Many2one('ir.attachment', string="报价清单")
|
||||
user_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
company_id = fields.Many2one(related='user_id.employee_id.company_id', string="公司")
|
||||
company_a_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
matters = fields.Text(string="事项")
|
||||
text = fields.Text(string="正文")
|
||||
license_id = fields.Many2one('ir.attachment', string='营业执照')
|
||||
aptitude_id = fields.Many2one('ir.attachment', string='资质')
|
||||
contract_id = fields.Many2one('ir.attachment', string='合同')
|
||||
legal_person_id_card = fields.Many2one('ir.attachment', string='法人身份证')
|
||||
bid_winning = fields.Many2one('ir.attachment', string='中标确认书')
|
||||
service_start_date = fields.Date(string="服务开始时间")
|
||||
service_end_date = fields.Date(string="服务结束时间")
|
||||
settlement_method = fields.Selection([('cash', '预算审核'), ('bank', '结算审核')], string='结算方式', default='cash')
|
||||
floating = fields.Float(string="下浮%")
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
active = fields.Boolean('Active', default=True, tracking=True)
|
||||
|
||||
@@ -4,27 +4,29 @@ from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
class PropertyDesignApproval(models.Model):
|
||||
_name = 'property.design.approval'
|
||||
_description = '工程设计合同审批'
|
||||
_description = '建设工程设计合同审批'
|
||||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||||
|
||||
name = fields.Char(string='标题')
|
||||
name = fields.Char(string='合同编号')
|
||||
code = fields.Char(string="编号",
|
||||
default=lambda self: self.env['ir.sequence'].next_by_code('property_design_approval_code'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
company_id = fields.Many2one(related='users_id.employee_id.company_id', string="公司")
|
||||
project_content = fields.Char(string="工程内容")
|
||||
company_a_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
property_id = fields.Many2one('yuthon.property', string='物业')
|
||||
budget_list_id = fields.Many2one('ir.attachment', string="预算清单")
|
||||
property_address = fields.Char(string='物业地址')
|
||||
reason = fields.Text(string="正文")
|
||||
three_point_offer = fields.Text(string="三方报价")
|
||||
image = fields.Binary(string="开工前图片")
|
||||
contract_id = fields.Many2one('ir.attachment', string="合同")
|
||||
start_date = fields.Date(string="开始日期")
|
||||
end_date = fields.Date(string="结束日期")
|
||||
review_price = fields.Float(string="审核价")
|
||||
business_type = fields.Char(string="业务类型")
|
||||
contract_amount = fields.Float(string="合同金额")
|
||||
payment_methods = fields.Char(string="付款方式")
|
||||
payment_methods = fields.Selection([('onetime', '一次性'), ('installment', '分期')], string="付款方式")
|
||||
lease_ids = fields.One2many('property.lease.contract.line', 'design_id', string="关联租赁信息")
|
||||
business_type = fields.Char(string="业务类型")
|
||||
design_way_ids = fields.One2many('design.way.line', 'design_id', string="关联支付方式")
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
@@ -37,14 +39,27 @@ class PropertyDesignApproval(models.Model):
|
||||
name_title = fields.Char(default=_get_default_name_title)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
|
||||
def build_pop(self):
|
||||
return {
|
||||
'name': '添加物业',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'build.pop.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_design_id': self.id,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DesignWayLine(models.Model):
|
||||
_name = 'design.way.line'
|
||||
_description = '施工支付方式'
|
||||
|
||||
name = fields.Char(string="支付节点")
|
||||
pay_ratio = fields.Float(string="支付比例%")
|
||||
payment_nodes = fields.Selection([('first', '一期'), ('second', '二期'), ('third', '三期'), ('fourth', '四期')],
|
||||
string="支付节点")
|
||||
payout_ratio = fields.Float(string="支付比例")
|
||||
amount = fields.Float(string="金额")
|
||||
paid_time = fields.Text(string="付费时间")
|
||||
remake = fields.Char(string="备注")
|
||||
payment_instructions = fields.Text(string="支付说明")
|
||||
design_id = fields.Many2one('property.design.approval', string="关联施工合同")
|
||||
@@ -216,11 +216,24 @@ class PropertyLeaseContract(models.Model):
|
||||
responsibility_book_name = fields.Char(string="安全生产责任书(住宅)名称", compute='_compute_attachment_names',
|
||||
store=True)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
title_information = fields.Text(string="产权证信息")
|
||||
title_information = fields.Text(string="产权证信息", compute='_compute_title_information')
|
||||
contract_count = fields.Integer(string="联系人数量", compute='_compute_contract_count')
|
||||
reconciliation_count = fields.Integer(string="对账数量", compute='_compute_reconciliation_count')
|
||||
process_count = fields.Integer(string="流程数量", compute='_compute_process_count')
|
||||
|
||||
@api.depends('lease_ids.address_id.title_deed')
|
||||
def _compute_title_information(self):
|
||||
for record in self:
|
||||
seen_titles = set()
|
||||
unique_titles = []
|
||||
for lease in record.lease_ids:
|
||||
if lease.address_id and lease.address_id.title_deed:
|
||||
title = lease.address_id.title_deed.strip()
|
||||
if title and title not in seen_titles:
|
||||
seen_titles.add(title)
|
||||
unique_titles.append(title)
|
||||
record.title_information = ', '.join(unique_titles)
|
||||
|
||||
def contract_signature(self):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
@@ -1645,6 +1658,11 @@ class PropertyLeaseContractLine(models.Model):
|
||||
_description = '物业列表明细行'
|
||||
|
||||
lease_id = fields.Many2one('property.lease.contract', string="关联凭租合同审批")
|
||||
construction_id = fields.Many2one('property.construction.approval', string="关联建设工程造价咨询合同审批")
|
||||
project_id = fields.Many2one('property.project.approval', string="关联工程立项")
|
||||
design_id = fields.Many2one('property.design.approval', string="关联建设工程设计合同审批")
|
||||
accounting_id = fields.Many2one('property.accounting.approval', string="关联建设工程委托监理合同审批")
|
||||
supervising_id = fields.Many2one('property.supervising.approval', string="关联建设工程施工合同审批")
|
||||
address_id = fields.Many2one('yuthon.property', string="物业地址")
|
||||
admin_line_id = fields.Many2one(related='address_id.admin_id', string="管理员")
|
||||
property_area = fields.Float(related='address_id.management_area', string="面积")
|
||||
|
||||
@@ -12,12 +12,13 @@ class PropertyProjectApproval(models.Model):
|
||||
default=lambda self: self.env['ir.sequence'].next_by_code('property_project_approval_code'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
property_id = fields.Many2one('yuthon.property', string='物业')
|
||||
property_address = fields.Char(string='物业地址')
|
||||
background_note = fields.Html(string="背景说明")
|
||||
documents_id = fields.Many2one('ir.attachment', string="建议书/可研报告")
|
||||
amount = fields.Float(string="预算金额")
|
||||
start_date = fields.Date(string="开始日期")
|
||||
end_date = fields.Date(string="结束日期")
|
||||
lease_ids = fields.One2many('property.lease.contract.line', 'project_id', string="物业信息")
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
active = fields.Boolean('Active', default=True, tracking=True)
|
||||
@@ -27,4 +28,16 @@ class PropertyProjectApproval(models.Model):
|
||||
return self._description if self._description else self._name
|
||||
|
||||
name_title = fields.Char(default=_get_default_name_title)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
|
||||
def build_pop(self):
|
||||
return {
|
||||
'name': '添加物业',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'build.pop.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_project_id': self.id,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,19 +4,25 @@ from odoo.exceptions import UserError
|
||||
|
||||
class PropertySporadicWorks(models.Model):
|
||||
_name = 'property.sporadic.works'
|
||||
_description = '委托招标代理'
|
||||
_description = '项目委托招标代理合同'
|
||||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||||
|
||||
name = fields.Char(string="工程名称", required=True)
|
||||
code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('property_sporadic_works_code'))
|
||||
name = fields.Char(string="合同编号", required=True)
|
||||
code = fields.Char(string="流水号", default=lambda self: self.env['ir.sequence'].next_by_code('property_sporadic_works_code'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
company_a_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
signing_date = fields.Date(string="签订日期")
|
||||
acceptance_date = fields.Date(string="验收日期")
|
||||
total = fields.Float(string="总金额")
|
||||
coping = fields.Float(string="应付")
|
||||
paid = fields.Float(string="已付")
|
||||
not_paid = fields.Float(string="未付")
|
||||
company_id = fields.Many2one(related='users_id.employee_id.company_id', string="公司")
|
||||
text = fields.Text(string="正文")
|
||||
three_quotation_id = fields.Many2one('ir.attachment', string="三方报价")
|
||||
service_contract = fields.Many2one('ir.attachment', string="服务合同")
|
||||
service_start_date = fields.Date(string="服务开始时间")
|
||||
service_end_date = fields.Date(string="服务结束时间")
|
||||
standard_amount = fields.Float(string="标准金额")
|
||||
service_fee = fields.Float(string="服务费")
|
||||
settlement_party = fields.Selection([('self' , '我方'), ('other', '中标方')], string="结算方")
|
||||
payment_methods = fields.Selection([('onetime', '一次性'), ('installment', '分期')], string="付款方式")
|
||||
payment_methods_line_ids = fields.One2many('payment.methods.line', 'payment_methods_id', string="付款方式明细行")
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
@@ -34,10 +40,10 @@ class PaymentMethodsLine(models.Model):
|
||||
_name = 'payment.methods.line'
|
||||
_description = '付款方式明细行'
|
||||
|
||||
name = fields.Char(string="合同阶段")
|
||||
payment_nodes = fields.Selection([('first', '一期' ), ('second', '二期'), ('third', '三期'), ('fourth', '四期')], string="支付节点")
|
||||
payout_ratio = fields.Float(string="支付比例")
|
||||
coping_date = fields.Date(string="应付日期")
|
||||
amount = fields.Float(string="金额")
|
||||
remake = fields.Char(string="备注")
|
||||
quotations_list_id = fields.Many2one('ir.attachment', string="报价清单")
|
||||
accounting_list_id = fields.Many2one('ir.attachment', string="核算清单")
|
||||
payment_instructions = fields.Text(string="支付说明")
|
||||
payment_methods_id = fields.Many2one('property.sporadic.works', string="关联付款方式")
|
||||
@@ -4,30 +4,35 @@ from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
class PropertySupervisingApproval(models.Model):
|
||||
_name = 'property.supervising.approval'
|
||||
_description = '工程设计合同审批'
|
||||
_description = '建设工程施工合同审批 '
|
||||
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
|
||||
|
||||
name = fields.Char(string='标题')
|
||||
code = fields.Char(string="编号",
|
||||
default=lambda self: self.env['ir.sequence'].next_by_code('property_supervising_code'))
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
project_content = fields.Char(string="工程内容")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
property_id = fields.Many2one('yuthon.property', string='物业')
|
||||
reason = fields.Text(string="正文")
|
||||
documents_ids = fields.Many2many('ir.attachment', string="附件")
|
||||
contract_id = fields.Many2one('ir.attachment', string="合同")
|
||||
start_date = fields.Date(string="开始日期")
|
||||
end_date = fields.Date(string="结束日期")
|
||||
review_price = fields.Float(string="审核价")
|
||||
business_type = fields.Char(string="业务类型")
|
||||
contract_amount = fields.Float(string="合同金额")
|
||||
payment_methods = fields.Char(string="付款方式")
|
||||
|
||||
supervising_way_ids = fields.One2many('supervising.way.line', 'supervising_id', string="关联支付方式")
|
||||
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')], string='紧急度',
|
||||
default='normal')
|
||||
users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id)
|
||||
department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门")
|
||||
company_id = fields.Many2one(related='users_id.employee_id.company_id', string="公司")
|
||||
company_a_id = fields.Many2one('yuthon.property.company', string="甲方")
|
||||
company_b_id = fields.Many2one('property.construction.unit', string="乙方")
|
||||
budget_list_id = fields.Many2one('ir.attachment', string="预算清单")
|
||||
property_address = fields.Char(string='物业地址')
|
||||
reason = fields.Text(string="正文")
|
||||
image = fields.Binary(string="开工前图片")
|
||||
contract_id = fields.Many2one('ir.attachment', string="合同")
|
||||
start_date = fields.Date(string="开始日期")
|
||||
project_content = fields.Char(string="工程内容")
|
||||
end_date = fields.Date(string="结束日期")
|
||||
review_price = fields.Float(string="审核价")
|
||||
floating = fields.Float(string="浮动")
|
||||
contract_amount = fields.Float(string="合同金额")
|
||||
payment_methods = fields.Selection([('onetime', '一次性'), ('installment', '分期')], string="付款方式")
|
||||
lease_ids = fields.One2many('property.lease.contract.line', 'supervising_id', string="物业信息明细")
|
||||
business_type = fields.Char(string="业务类型")
|
||||
active = fields.Boolean('Active', default=True, tracking=True)
|
||||
work_end = fields.Boolean(string="结束")
|
||||
|
||||
@@ -37,11 +42,24 @@ class PropertySupervisingApproval(models.Model):
|
||||
name_title = fields.Char(default=_get_default_name_title)
|
||||
self_users_ids = fields.Many2many('res.users', string="当前经办人", default=lambda self: [(6, 0, [self.env.user.id])])
|
||||
|
||||
def build_pop(self):
|
||||
return {
|
||||
'name': '添加物业',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'build.pop.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_supervising_id': self.id,
|
||||
}
|
||||
}
|
||||
|
||||
class SupervisingWayLine(models.Model):
|
||||
_name = 'supervising.way.line'
|
||||
_description = '施工支付方式'
|
||||
|
||||
name = fields.Char(string="支付节点")
|
||||
payment_nodes = fields.Selection([('first', '一期'), ('second', '二期'), ('third', '三期'), ('fourth', '四期')],
|
||||
string="支付节点")
|
||||
pay_ratio = fields.Float(string="支付比例%")
|
||||
amount = fields.Float(string="金额")
|
||||
remake = fields.Char(string="备注")
|
||||
|
||||
@@ -102,5 +102,6 @@ access_binding_information_wizard,binding_information_wizard,model_binding_infor
|
||||
access_yuthon_property_ledger, yuthon_property_ledger,model_yuthon_property_ledger,base.group_user,1,1,1,1
|
||||
access_property_lessee_analysis,property_lessee_analysis,model_property_lessee_analysis,base.group_user,1,1,1,1
|
||||
access_contract_signature_wizard,contract_signature_wizard,model_contract_signature_wizard,base.group_user,1,1,1,1
|
||||
|
||||
access_payment_process,payment_process,model_payment_process,base.group_user,1,1,1,1
|
||||
access_build_pop_wizard, build_pop_wizard,model_build_pop_wizard,base.group_user,1,1,1,1
|
||||
|
||||
|
||||
|
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="view_payment_process_tree" model="ir.ui.view">
|
||||
<field name="name">payment.process.tree</field>
|
||||
<field name="model">payment.process</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="支付流程">
|
||||
<field name="supervising_id"/>
|
||||
<field name="reason"/>
|
||||
<field name="payment_instructions"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_payment_process_form" model="ir.ui.view">
|
||||
<field name="name">payment.process.form</field>
|
||||
<field name="model">payment.process</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="支付流程">
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="普件" bg_color="text-bg-success"
|
||||
invisible="urgency_level != 'normal'"/>
|
||||
<widget name="web_ribbon" title="急件" bg_color="text-bg-warning"
|
||||
invisible="urgency_level != 'urgent'"/>
|
||||
<widget name="web_ribbon" title="特级" bg_color="text-bg-danger"
|
||||
invisible="urgency_level != 'emergency'"/>
|
||||
<group col="3">
|
||||
<group>
|
||||
<field name="code" string="流水号" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="urgency_level" readonly="1"/>
|
||||
</group>
|
||||
<group/>
|
||||
</group>
|
||||
<div class="col-12 text-center">
|
||||
<h1>
|
||||
<field name="name_title" readonly="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group string="审批事项">
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="users_id"/>
|
||||
<field name="supervising_id"/>
|
||||
<field name="reason"/>
|
||||
<field name="payment_instructions"/>
|
||||
<field name="payment_nodes"/>
|
||||
<field name="amount"/>
|
||||
<field name="documents_id" widget="preview_many2one"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -4,7 +4,7 @@
|
||||
<field name="name">property.accounting.approval.tree</field>
|
||||
<field name="model">property.accounting.approval</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="建设工程委托核算合同审批">
|
||||
<tree string="建设工程委托监理合同审批">
|
||||
<field name="name"/>
|
||||
<field name="company_id" required="1"/>
|
||||
<field name="company_b_id"/>
|
||||
@@ -17,7 +17,7 @@
|
||||
<field name="name">property.accounting.approval.form</field>
|
||||
<field name="model">property.accounting.approval</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="建设工程委托核算合同审批" create="0">
|
||||
<form string="建设工程委托监理合同审批" create="0">
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="普件" bg_color="text-bg-success"
|
||||
invisible="urgency_level != 'normal'"/>
|
||||
@@ -42,49 +42,58 @@
|
||||
<group>
|
||||
<field name="name" required="1" string="合同编号:"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="company_id" required="1"/>
|
||||
<field name="project_content"/>
|
||||
<field name="users_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_a_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_b_id" options="{'no_create': True}"/>
|
||||
<field name="property_id" options="{'no_create': True}"/>
|
||||
<field name="company_b_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="users_id"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="property_address"/>
|
||||
<field name="reason"/>
|
||||
<field name="three_point_offer"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<field name="image"/>
|
||||
<field name="budget_list_id" widget="preview_many2one"/>
|
||||
<field name="contract_id" widget="preview_many2one"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="start_date"/>
|
||||
<field name="amount"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="end_date"/>
|
||||
<field name="is_tex"/>
|
||||
</group>
|
||||
</group>
|
||||
<label for="lack"/>
|
||||
<label for="start_date"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="lack" class="me-2" style="max-width: 11rem !important;" string=" "/>不足
|
||||
<field name="percentage" class="me-2" style="max-width: 11rem !important;"/>元收百分比
|
||||
<field name="start_date" class="me-2" style="max-width: 7rem;"
|
||||
string="代理期限"/>至
|
||||
<field name="end_date" class="me-2" style="max-width: 7rem;"
|
||||
force_save="1"/>
|
||||
</div>
|
||||
<field name="contract_amount"/>
|
||||
<field name="business_type"/>
|
||||
<field name="payment_methods"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="project_content"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="物业信息">
|
||||
<button name="build_pop" string="添加物业" type="object"
|
||||
class="btn-primary"/>
|
||||
<field name="lease_ids">
|
||||
<tree editable="bottom" create="false">
|
||||
<field name="accounting_id" column_invisible="1"/>
|
||||
<field name="address_id"/>
|
||||
<field name="admin_line_id"/>
|
||||
<field name="property_area"/>
|
||||
<field name="evaluate_unit_price"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="支付方式">
|
||||
<field name="accounting_way_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="accounting_id" column_invisible="1"/>
|
||||
<field name="pay_way"/>
|
||||
<field name="interval"/>
|
||||
<field name="service_charge"/>
|
||||
<field name="remake"/>
|
||||
<field name="accounting_id" column_invisible="1"/>
|
||||
<field name="payment_nodes"/>
|
||||
<field name="amount"/>
|
||||
<field name="remake"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
@@ -94,7 +103,7 @@
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_property_accounting_approval_action" model="ir.actions.act_window">
|
||||
<field name="name">核算审批</field>
|
||||
<field name="name">建设工程委托监理合同审批</field>
|
||||
<field name="res_model">property.accounting.approval</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
invisible="urgency_level != 'emergency'"/>
|
||||
<group col="3">
|
||||
<group>
|
||||
<field name="code" string="流水号" readonly="1"/>
|
||||
<field name="code" string="合同编号" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="urgency_level" readonly="1"/>
|
||||
@@ -40,49 +40,60 @@
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="name" required="1" string="合同编号:"/>
|
||||
<field name="name" readonly="1"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="company_id" required="1"/>
|
||||
<field name="project_content"/>
|
||||
<field name="users_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_a_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_b_id" options="{'no_create': True}"/>
|
||||
<field name="property_id" options="{'no_create': True}"/>
|
||||
<field name="company_b_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_id"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="property_address"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="reason"/>
|
||||
<field name="image"/>
|
||||
<field name="budget_list_id" widget="preview_many2one"/>
|
||||
<field name="contract_id" widget="preview_many2one"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="contract_amount"/>
|
||||
<field name="start_date"/>
|
||||
<field name="review_price"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="payment_methods"/>
|
||||
<field name="end_date"/>
|
||||
<field name="business_type"/>
|
||||
</group>
|
||||
<label for="start_date"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="start_date" class="me-2" style="max-width: 7rem;"
|
||||
string="代理期限"/>至
|
||||
<field name="end_date" class="me-2" style="max-width: 7rem;"
|
||||
force_save="1"/>
|
||||
</div>
|
||||
<field name="contract_amount"/>
|
||||
<field name="business_type"/>
|
||||
<field name="payment_methods"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="物业信息">
|
||||
<button name="build_pop" string="添加物业" type="object"
|
||||
class="btn-primary"/>
|
||||
<field name="lease_ids">
|
||||
<tree editable="bottom" create="false">
|
||||
<field name="construction_id" column_invisible="1"/>
|
||||
<field name="address_id"/>
|
||||
<field name="admin_line_id"/>
|
||||
<field name="property_area"/>
|
||||
<field name="evaluate_unit_price"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="支付方式">
|
||||
<field name="construction_way_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="construction_id" column_invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="pay_ratio"/>
|
||||
<tree editable="bottom">
|
||||
<field name="construction_id" column_invisible="1"/>
|
||||
<field name="payment_nodes"/>
|
||||
<field name="coping_date"/>
|
||||
<field name="amount"/>
|
||||
<field name="paid_time"/>
|
||||
<field name="remake"/>
|
||||
</tree>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="零星工程">
|
||||
<field name="name"/>
|
||||
<field name="annual"/>
|
||||
<field name="contract_date"/>
|
||||
<field name="payment_date"/>
|
||||
<field name="consult_fee"/>
|
||||
<field name="service_start_date"/>
|
||||
<field name="service_end_date"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -45,14 +43,43 @@
|
||||
<field name="name" required="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="company_a_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_b_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_id"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="annual"/>
|
||||
<field name="contract_date"/>
|
||||
<field name="signing_date"/>
|
||||
<field name="payment_date"/>
|
||||
<field name="consult_fee"/>
|
||||
<field name="quotations_list_id" widget="preview_many2one"/>
|
||||
<field name="matters"/>
|
||||
<field name="text"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="license_id" widget="preview_many2one"/>
|
||||
<field name="aptitude_id" widget="preview_many2one"/>
|
||||
<field name="contract_id" widget="preview_many2one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="legal_person_id_card" widget="preview_many2one"/>
|
||||
<field name="bid_winning" widget="preview_many2one"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<label for="service_start_date"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="service_start_date" class="me-2" style="max-width: 7rem;"
|
||||
string="服务期限"/>至
|
||||
<field name="service_end_date" class="me-2" style="max-width: 7rem;"
|
||||
force_save="1"/>
|
||||
</div>
|
||||
<field name="settlement_method"/>
|
||||
<field name="floating"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
|
||||
@@ -44,43 +44,55 @@
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="company_id" required="1"/>
|
||||
<field name="project_content"/>
|
||||
<field name="users_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_a_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_b_id" options="{'no_create': True}"/>
|
||||
<field name="property_id" options="{'no_create': True}"/>
|
||||
<field name="company_b_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="users_id"/>
|
||||
<field name="property_address"/>
|
||||
<field name="reason"/>
|
||||
<field name="three_point_offer"/>
|
||||
<field name="image"/>
|
||||
<field name="budget_list_id" widget="preview_many2one"/>
|
||||
<field name="contract_id" widget="preview_many2one"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="contract_amount"/>
|
||||
<field name="start_date"/>
|
||||
<field name="review_price"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="payment_methods"/>
|
||||
<field name="end_date"/>
|
||||
<field name="business_type"/>
|
||||
</group>
|
||||
<label for="start_date"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="start_date" class="me-2" style="max-width: 7rem;"
|
||||
string="合同期限"/>至
|
||||
<field name="end_date" class="me-2" style="max-width: 7rem;"
|
||||
force_save="1"/>
|
||||
</div>
|
||||
<field name="contract_amount"/>
|
||||
<field name="business_type"/>
|
||||
<field name="payment_methods"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="project_content"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="物业信息">
|
||||
<button name="build_pop" string="添加物业" type="object"
|
||||
class="btn-primary"/>
|
||||
<field name="lease_ids">
|
||||
<tree editable="bottom" create="false">
|
||||
<field name="design_id" column_invisible="1"/>
|
||||
<field name="address_id"/>
|
||||
<field name="admin_line_id"/>
|
||||
<field name="property_area"/>
|
||||
<field name="evaluate_unit_price"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="支付方式">
|
||||
<field name="design_way_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="design_id" column_invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="pay_ratio"/>
|
||||
<field name="payment_nodes"/>
|
||||
<field name="amount"/>
|
||||
<field name="paid_time"/>
|
||||
<field name="remake"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -92,7 +104,7 @@
|
||||
</record>
|
||||
<record id="view_property_design_approval_action" model="ir.actions.act_window">
|
||||
<field name="name">建设工程设计合同审批</field>
|
||||
<field name="res_model">property.construction.approval</field>
|
||||
<field name="res_model">property.design.approval</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="项目立项审批">
|
||||
<field name="name"/>
|
||||
<field name="property_id"/>
|
||||
<field name="property_address"/>
|
||||
<field name="amount"/>
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
@@ -42,15 +42,30 @@
|
||||
<group>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="name" required="1" string="项目名称:"/>
|
||||
<field name="property_address"/>
|
||||
<field name="users_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="property_id" options="{'no_create': True}"/>
|
||||
<field name="background_note"/>
|
||||
<field name="amount"/>
|
||||
<field name="documents_id" widget="preview_many2one"/>
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="物业信息">
|
||||
<button name="build_pop" string="添加物业" type="object"
|
||||
class="btn-primary"/>
|
||||
<field name="lease_ids">
|
||||
<tree editable="bottom" create="false">
|
||||
<field name="project_id" column_invisible="1"/>
|
||||
<field name="address_id"/>
|
||||
<field name="admin_line_id"/>
|
||||
<field name="property_area"/>
|
||||
<field name="evaluate_unit_price"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
<field name="name">property.sporadic.works.tree</field>
|
||||
<field name="model">property.sporadic.works</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="委托招标代理">
|
||||
<tree string="项目委托招标代理合同">
|
||||
<field name="name"/>
|
||||
<field name="signing_date"/>
|
||||
<field name="acceptance_date"/>
|
||||
<field name="total"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -16,7 +13,7 @@
|
||||
<field name="name">property.sporadic.works.form</field>
|
||||
<field name="model">property.sporadic.works</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="委托招标代理" create="0">
|
||||
<form string="项目委托招标代理合同" create="0">
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="普件" bg_color="text-bg-success"
|
||||
invisible="urgency_level != 'normal'"/>
|
||||
@@ -44,27 +41,47 @@
|
||||
<field name="name" required="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="company_a_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_b_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="signing_date"/>
|
||||
<field name="acceptance_date"/>
|
||||
<field name="total"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="coping"/>
|
||||
<field name="paid"/>
|
||||
<field name="not_paid"/>
|
||||
<field name="users_id" invisible="1"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="text"/>
|
||||
<field name="three_quotation_id" widget="preview_many2one"/>
|
||||
<field name="service_contract" widget="preview_many2one"/>
|
||||
<label for="service_start_date"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="service_start_date" class="me-2" style="max-width: 7rem;"
|
||||
string="服务期限"/>至
|
||||
<field name="service_end_date" class="me-2" style="max-width: 7rem;"
|
||||
force_save="1"/>
|
||||
</div>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="standard_amount"/>
|
||||
<field name="service_fee"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="settlement_party"/>
|
||||
<field name="payment_methods"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="付款方式">
|
||||
<field name="payment_methods_line_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="payment_nodes"/>
|
||||
<field name="coping_date"/>
|
||||
<field name="amount"/>
|
||||
<field name="remake"/>
|
||||
<field name="quotations_list_id" widget="preview_many2one"/>
|
||||
<field name="accounting_list_id" widget="preview_many2one"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
@@ -42,43 +42,58 @@
|
||||
<group>
|
||||
<field name="name" required="1" string="合同编号:"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="company_id" required="1"/>
|
||||
<field name="project_content"/>
|
||||
<field name="users_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_a_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_b_id"/>
|
||||
<field name="property_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="users_id"/>
|
||||
<field name="property_address"/>
|
||||
<field name="reason"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<field name="image"/>
|
||||
<field name="budget_list_id" widget="preview_many2one"/>
|
||||
<field name="contract_id" widget="preview_many2one"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="contract_amount"/>
|
||||
<field name="start_date"/>
|
||||
<field name="review_price"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="payment_methods"/>
|
||||
<field name="end_date"/>
|
||||
<field name="business_type"/>
|
||||
</group>
|
||||
<label for="start_date"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="start_date" class="me-2" style="max-width: 7rem;"
|
||||
string="代理期限"/>至
|
||||
<field name="end_date" class="me-2" style="max-width: 7rem;"
|
||||
force_save="1"/>
|
||||
</div>
|
||||
<field name="review_price"/>
|
||||
<field name="floating"/>
|
||||
<field name="contract_amount"/>
|
||||
<field name="business_type"/>
|
||||
<field name="payment_methods"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="project_content"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="物业信息">
|
||||
<button name="build_pop" string="添加物业" type="object"
|
||||
class="btn-primary"/>
|
||||
<field name="lease_ids">
|
||||
<tree editable="bottom" create="false">
|
||||
<field name="supervising_id" column_invisible="1"/>
|
||||
<field name="address_id"/>
|
||||
<field name="admin_line_id"/>
|
||||
<field name="property_area"/>
|
||||
<field name="evaluate_unit_price"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="支付方式">
|
||||
<field name="supervising_way_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="supervising_id" column_invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="pay_ratio"/>
|
||||
<field name="payment_nodes"/>
|
||||
<field name="amount"/>
|
||||
<field name="remake"/>
|
||||
</tree>
|
||||
@@ -91,7 +106,7 @@
|
||||
</record>
|
||||
<record id="view_property_supervising_approval_action" model="ir.actions.act_window">
|
||||
<field name="name">建设工程委托监理合同审批</field>
|
||||
<field name="res_model">property.construction.approval</field>
|
||||
<field name="res_model">property.supervising.approval</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -9,4 +9,5 @@ from . import property_management_wizard
|
||||
from . import click_reconciliation_wizard
|
||||
from . import accounts_wizard
|
||||
from . import binding_information_wizard
|
||||
from . import contract_signature_wizard
|
||||
from . import contract_signature_wizard
|
||||
from . import build_pop_wizard
|
||||
@@ -0,0 +1,48 @@
|
||||
from odoo import models, fields, api, _, SUPERUSER_ID
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class BuildPopWizard(models.TransientModel):
|
||||
_name = 'build.pop.wizard'
|
||||
_description = '添加物业弹窗'
|
||||
|
||||
property_ids = fields.Many2many('yuthon.property', string='物业')
|
||||
construction_id = fields.Many2one('property.construction.approval', string="关联建设工程造价咨询合同审批")
|
||||
project_id = fields.Many2one('property.project.approval', string="关联工程立项")
|
||||
design_id = fields.Many2one('property.design.approval', string="关联建设工程设计合同审批")
|
||||
accounting_id = fields.Many2one('property.accounting.approval', string="关联建设工程委托监理合同审批")
|
||||
supervising_id = fields.Many2one('property.supervising.approval', string="关联建设工程施工合同审批")
|
||||
|
||||
def confirm(self):
|
||||
# 收集所有选中物业的地址
|
||||
property_addresses = [
|
||||
prop.name
|
||||
for prop in self.property_ids
|
||||
if prop.name
|
||||
]
|
||||
concatenated_address = ', '.join(property_addresses)
|
||||
related_fields = [
|
||||
('construction_id', 'construction_id'),
|
||||
('project_id', 'project_id'),
|
||||
('design_id', 'design_id'),
|
||||
('accounting_id', 'accounting_id'),
|
||||
('supervising_id', 'supervising_id')
|
||||
]
|
||||
|
||||
for field, line_field in related_fields:
|
||||
record = getattr(self, field)
|
||||
if record:
|
||||
if hasattr(record, 'property_address'):
|
||||
record.write({'property_address': concatenated_address})
|
||||
|
||||
existing_lines = self.env['property.lease.contract.line'].search([
|
||||
(line_field, '=', record.id)
|
||||
])
|
||||
if existing_lines:
|
||||
existing_lines.unlink()
|
||||
|
||||
for prop in self.property_ids:
|
||||
self.env['property.lease.contract.line'].create({
|
||||
line_field: record.id,
|
||||
'address_id': prop.id,
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="build_pop_wizard_form" model="ir.ui.view">
|
||||
<field name="name">build.pop.wizard.form</field>
|
||||
<field name="model">build.pop.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="property_ids" widget="many2many_tags"/>
|
||||
<field name="construction_id" invisible="1"/>
|
||||
<field name="project_id" invisible="1"/>
|
||||
<field name="design_id" invisible="1"/>
|
||||
<field name="accounting_id" invisible="1"/>
|
||||
<field name="supervising_id" invisible="1"/>
|
||||
</group>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button name="confirm" string="确认" type="object" class="oe_highlight"/>
|
||||
<button string="返回" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -66,12 +66,6 @@ class ChoosePropertyWizard(models.Model):
|
||||
name_val = lease.address_id.name
|
||||
existing_names.append(name_val if name_val is not None else "无")
|
||||
|
||||
information_names = []
|
||||
for lease in self.lease_contract_id.lease_ids:
|
||||
if lease.address_id and lease.address_id.title_deed != '无产权':
|
||||
deed_val = lease.address_id.title_deed
|
||||
information_names.append(str(deed_val) if deed_val is not None else "无")
|
||||
|
||||
title_name = []
|
||||
for lease in self.lease_contract_id.lease_ids:
|
||||
if lease.address_id:
|
||||
@@ -80,7 +74,6 @@ class ChoosePropertyWizard(models.Model):
|
||||
|
||||
# 过滤空字符串,避免拼接时出现空内容
|
||||
all_names = [name for name in list(set(existing_names + lease_name)) if name]
|
||||
title_information = [info for info in list(set(information_names + title_deed))]
|
||||
title_address_combined = [addr for addr in list(set(title_address + title_name)) if addr]
|
||||
|
||||
existing_lease_ids = [(4, lease.id) for lease in self.lease_contract_id.lease_ids]
|
||||
@@ -94,7 +87,6 @@ class ChoosePropertyWizard(models.Model):
|
||||
if self.lease_contract_id.lease_ids else False,
|
||||
'use_address': ','.join(all_names),
|
||||
'address_for_delivery': ','.join(all_names),
|
||||
'title_information': ','.join(title_information),
|
||||
'total_area': sum([lease.property_area for lease in rec.lease_ids])
|
||||
})
|
||||
|
||||
|
||||
@@ -178,8 +178,8 @@ class PropertyRentalWizard(models.Model):
|
||||
start_year_month = start_date_adj.strftime('%Y-%m')
|
||||
end_year_month = rent_id.end_data.strftime('%Y-%m')
|
||||
start_day = start_date_adj.day
|
||||
# 通过period_month 来判断是否有免租期,则使用 period_rent,否则使用 monthly_amount
|
||||
rent_amount = rent_id.period_rent if period_month else rent_id.monthly_amount
|
||||
# 通过period_month 来判断是否有免租期,则使用 ,否则月租金使用 期间租金
|
||||
rent_amount = rent_id.monthly_amount if period_month else rent_id.period_rent
|
||||
if is_year:
|
||||
if rent_id.month_number >12:
|
||||
multiplier = rent_id.month_number - 12
|
||||
|
||||
Reference in New Issue
Block a user