Merge branch 'refs/heads/dev' into dev_zhou
# Conflicts: # yuthon_property_approval/views/property_lease_contract.xml
This commit is contained in:
@@ -47,7 +47,8 @@ class BusController(Controller):
|
||||
user_id = data.get('logs')[0].get('user_id')
|
||||
employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('mobile_phone', '=', user_id)])
|
||||
recog_time_str = data.get('logs')[0].get("recog_time")
|
||||
checkin_time = datetime.strptime(recog_time_str, "%Y-%m-%d %H:%M:%S") + timedelta(hours=8)
|
||||
# checkin_time = datetime.strptime(recog_time_str, "%Y-%m-%d %H:%M:%S") + timedelta(hours=8)
|
||||
checkin_time = datetime.strptime(recog_time_str, "%Y-%m-%d %H:%M:%S")
|
||||
attendance_iot_id = request.env(user=SUPERUSER_ID)["attendance.iot"].search([('name', '=', data.get('sn'))])
|
||||
if employee_id:
|
||||
request.env(user=SUPERUSER_ID)["hr.attendance.detail"].create({
|
||||
@@ -76,8 +77,7 @@ class BusController(Controller):
|
||||
if not iot_device:
|
||||
request.env(user=SUPERUSER_ID)["attendance.iot"].create({'name': sn})
|
||||
iot_users = request.env(user=SUPERUSER_ID)['attendance.iot.user'].search([('employee_id', '=', employee.id)])
|
||||
employee.write({'image_1920': urllib.parse.unquote(vl_photo)})
|
||||
# 2025-06-17 08:35:41,017 12200 WARNING 2561223 odoo.http: 该文件无法作为图像文件解码。
|
||||
employee.write({'image_1920': base64.b64encode(urllib.parse.unquote(vl_photo))})
|
||||
if not iot_users:
|
||||
request.env(user=SUPERUSER_ID)['attendance.iot.user'].create({
|
||||
'employee_id': employee.id,
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import controllers
|
||||
from . import models
|
||||
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': "oo_list_manager",
|
||||
|
||||
'summary': "Short (1 phrase/line) summary of the module's purpose",
|
||||
|
||||
'description': """
|
||||
Long description of module's purpose
|
||||
""",
|
||||
|
||||
'author': "My Company",
|
||||
'website': "https://www.yourcompany.com",
|
||||
|
||||
# Categories can be used to filter modules in modules listing
|
||||
# Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
|
||||
# for the full list
|
||||
'category': 'Uncategorized',
|
||||
'version': '0.1',
|
||||
|
||||
# any module necessary for this one to work correctly
|
||||
'depends': ['base', 'web', 'tree_view_advanced_filter'],
|
||||
|
||||
# always loaded
|
||||
'data': [
|
||||
# 'security/ir.model.access.csv',
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
"application": True,
|
||||
"auto_install": False,
|
||||
'license': 'LGPL-3',
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'oo_list_manager/static/src/views/list/*',
|
||||
'oo_list_manager/static/src/views/auto_hide_list/*',
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import controllers
|
||||
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# from odoo import http
|
||||
|
||||
|
||||
# class OoListManager(http.Controller):
|
||||
# @http.route('/oo_list_manager/oo_list_manager', auth='public')
|
||||
# def index(self, **kw):
|
||||
# return "Hello, world"
|
||||
|
||||
# @http.route('/oo_list_manager/oo_list_manager/objects', auth='public')
|
||||
# def list(self, **kw):
|
||||
# return http.request.render('oo_list_manager.listing', {
|
||||
# 'root': '/oo_list_manager/oo_list_manager',
|
||||
# 'objects': http.request.env['oo_list_manager.oo_list_manager'].search([]),
|
||||
# })
|
||||
|
||||
# @http.route('/oo_list_manager/oo_list_manager/objects/<model("oo_list_manager.oo_list_manager"):obj>', auth='public')
|
||||
# def object(self, obj, **kw):
|
||||
# return http.request.render('oo_list_manager.object', {
|
||||
# 'object': obj
|
||||
# })
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import ir_ui_view
|
||||
@@ -0,0 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class IrUiView(models.Model):
|
||||
_inherit = 'ir.ui.view'
|
||||
|
||||
manager_data = fields.Json(string='data')
|
||||
|
||||
def get_manager_data(self):
|
||||
self.ensure_one()
|
||||
return self.manager_data or {}
|
||||
|
||||
def save_manager_data(self, manager_data):
|
||||
self.ensure_one()
|
||||
self.sudo().write({
|
||||
'manager_data': manager_data
|
||||
})
|
||||
return True
|
||||
@@ -0,0 +1,2 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_oo_list_manager_oo_list_manager,oo_list_manager.oo_list_manager,model_oo_list_manager_oo_list_manager,base.group_user,1,1,1,1
|
||||
|
@@ -0,0 +1,30 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
||||
|
||||
export class AutoHideListRenderer extends ListRenderer {
|
||||
|
||||
getActiveColumns(list) {
|
||||
const columns = super.getActiveColumns(list);
|
||||
let values;
|
||||
if (this.props.list.selection && this.props.list.selection.length) {
|
||||
values = this.props.list.selection.map((r) => r.data);
|
||||
} else if (this.props.list.isGrouped) {
|
||||
values = this.props.list.groups.map((g) => g.aggregates);
|
||||
} else {
|
||||
values = this.props.list.records.map((r) => r.data);
|
||||
}
|
||||
return columns.filter(column => {
|
||||
const fieldInfo = list.fields[column.name];
|
||||
if (["float", "integer", "monetary"].includes(fieldInfo.type)) {
|
||||
const fieldValues = values.map((v) => v[fieldInfo.name] || 0);
|
||||
const aggregateValue = fieldValues.reduce((acc, val) => acc + val);
|
||||
if (!aggregateValue) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { listView } from "@web/views/list/list_view";
|
||||
import { AutoHideListRenderer } from "./auto_hide_list_renderer";
|
||||
|
||||
export const autoHideListView = {
|
||||
...listView,
|
||||
Renderer: AutoHideListRenderer
|
||||
}
|
||||
|
||||
registry.category("views").add("autoHideListView", autoHideListView);
|
||||
@@ -0,0 +1,156 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {ListController} from "@web/views/list/list_controller";
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
import {onWillStart, useState, useRef, useExternalListener} from "@odoo/owl";
|
||||
import {Dropdown} from "@web/core/dropdown/dropdown";
|
||||
import {CheckBox} from "@web/core/checkbox/checkbox";
|
||||
import {useSortable} from "@web/core/utils/sortable_owl";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
import {usePosition} from "@web/core/position_hook";
|
||||
|
||||
|
||||
patch(ListController.prototype, {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.isChange = false;
|
||||
this.orm = useService('orm');
|
||||
this.ooColumnsRef = useRef('ooColumnsRef');
|
||||
this.ooManagerRef = useRef('ooManagerRef');
|
||||
this.ooListRef = useRef('ooListRef');
|
||||
|
||||
this.ooManager = useState({
|
||||
state: false,
|
||||
key: '',
|
||||
filter: false,
|
||||
serial_num: false,
|
||||
columns: this.archInfo.columns.filter((column) => {
|
||||
if (column.type === "field" && column.widget !== 'handle') {
|
||||
return column
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
onWillStart(async () => {
|
||||
const manager_data = await this.orm.call('ir.ui.view', 'get_manager_data', [this.env.config.viewId]);
|
||||
if (!Object.keys(manager_data).length) {
|
||||
this.ooManager.columns.forEach(val => {
|
||||
val.visibility = !!!val.column_invisible;
|
||||
})
|
||||
} else {
|
||||
Object.assign(this.ooManager, manager_data);
|
||||
this.archInfo.advanced_filter = this.ooManager.filter;
|
||||
}
|
||||
})
|
||||
|
||||
usePosition('ooListRef', () => this.ooManagerRef.el, {
|
||||
position: "bottom-start",
|
||||
})
|
||||
|
||||
useSortable({
|
||||
ref: this.ooColumnsRef,
|
||||
elements: ".oo_column",
|
||||
handle: ".oo_sort_cell",
|
||||
cursor: "move",
|
||||
onDrop: (params) => this.sortColumnDrop(params)
|
||||
})
|
||||
|
||||
useExternalListener(window, "click", this.onGlobalClick.bind(this));
|
||||
},
|
||||
|
||||
onGlobalClick(ev) {
|
||||
if (this.ooListRef.el && !this.ooListRef.el.contains(ev.target)) {
|
||||
this.ooManager.state = false;
|
||||
this.ooManager.key = '';
|
||||
if (this.isChange) {
|
||||
return this.saveManagerData();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onChangeSerialNum() {
|
||||
this.isChange = true;
|
||||
this.ooManager.serial_num = !this.ooManager.serial_num;
|
||||
},
|
||||
|
||||
onChangeFilter() {
|
||||
this.isChange = true;
|
||||
this.ooManager.filter = !this.ooManager.filter;
|
||||
this.archInfo.advanced_filter = this.ooManager.filter;
|
||||
},
|
||||
|
||||
onChangeColumns() {
|
||||
const columns = [...this.ooManager.columns];
|
||||
this.isChange = true;
|
||||
this.ooManager.columns = columns;
|
||||
},
|
||||
|
||||
/**
|
||||
* 控制列显示/隐藏
|
||||
* @param ev
|
||||
*/
|
||||
onChangeVisibility(ev) {
|
||||
const id = ev.currentTarget.dataset.id;
|
||||
const columns = [...this.ooManager.columns];
|
||||
const columnIdx = columns.findIndex(item => item.id === id);
|
||||
if (columnIdx >= 0) {
|
||||
columns[columnIdx].visibility = !columns[columnIdx].visibility;
|
||||
}
|
||||
this.isChange = true;
|
||||
this.ooManager.columns = columns;
|
||||
},
|
||||
|
||||
/**
|
||||
* 排序
|
||||
* @param params
|
||||
*/
|
||||
sortColumnDrop(params) {
|
||||
const {element, previous} = params;
|
||||
|
||||
const fromId = element.dataset.id;
|
||||
const toId = previous ? previous.dataset.id : null;
|
||||
const columns = [...this.ooManager.columns];
|
||||
const fromIndex = columns.findIndex((d) => d.id === fromId);
|
||||
let toIndex = 0;
|
||||
if (toId !== null) {
|
||||
const targetIndex = columns.findIndex((d) => d.id === toId);
|
||||
toIndex = fromIndex > targetIndex ? targetIndex + 1 : targetIndex;
|
||||
}
|
||||
|
||||
// 取出被拖拽的元素
|
||||
const [moved] = columns.splice(fromIndex, 1);
|
||||
// 插入到新位置
|
||||
columns.splice(toIndex, 0, moved);
|
||||
columns.forEach((column, i) => {
|
||||
column.seq = i + 1;
|
||||
});
|
||||
this.isChange = true;
|
||||
this.ooManager.columns = columns;
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存
|
||||
* @returns {*}
|
||||
*/
|
||||
saveManagerData() {
|
||||
this.isChange = false;
|
||||
return this.orm.call(
|
||||
'ir.ui.view',
|
||||
'save_manager_data',
|
||||
[
|
||||
this.env.config.viewId,
|
||||
{
|
||||
columns: this.ooManager.columns,
|
||||
filter: this.ooManager.filter,
|
||||
serial_num: this.ooManager.serial_num,
|
||||
}
|
||||
]
|
||||
);
|
||||
},
|
||||
})
|
||||
|
||||
ListController.components = {
|
||||
...ListController.components,
|
||||
Dropdown,
|
||||
CheckBox
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
.oo_list_manager {
|
||||
padding: 10px 10px 0 10px;
|
||||
overflow: hidden;
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
z-index: 999999999999999;
|
||||
left: 0;
|
||||
|
||||
.oo_columns {
|
||||
overflow: auto;
|
||||
|
||||
.oo_column {
|
||||
background-color: white;
|
||||
|
||||
.o_width_input {
|
||||
width: 50px;
|
||||
appearance: textfield;
|
||||
margin: 0 5px 0 5px;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_lock_box {
|
||||
margin: 0 5px 0 5px;
|
||||
padding: 0 5px 0 5px;
|
||||
|
||||
i {
|
||||
display: block;
|
||||
font-size: 1.4rem;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #27ae60;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #27ae60;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-inherit="web.ListView" t-inherit-mode="extension">
|
||||
<xpath expr="//t[@t-set-slot='layout-buttons']" position="inside">
|
||||
<div class="o-dropdown dropdown o-dropdown--no-caret" t-ref="ooManagerRef">
|
||||
<button type="button" class="btn btn-primary" t-on-click="()=>this.ooManager.state = !this.ooManager.state">
|
||||
<i class="fa fa-cogs" />
|
||||
</button>
|
||||
<div class="oo_list_manager o-dropdown--menu dropdown-menu d-block" t-if="ooManager.state" t-ref="ooListRef">
|
||||
<div class="d-flex align-items-center pb-2">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
表头查询:
|
||||
</div>
|
||||
<div class="o-checkbox form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" t-model="ooManager.filter" t-on-click="onChangeFilter"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
行号:
|
||||
</div>
|
||||
<div class="o-checkbox form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" t-model="ooManager.serial_num" t-on-click="onChangeSerialNum"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center pb-2">
|
||||
<input type="text" class="form-control" t-model="ooManager.key"/>
|
||||
<i class="btn btn-primary fa fa-refresh ms-2" t-on-click="()=>this.ooManager.key = ''"/>
|
||||
</div>
|
||||
<div class="d-flex flex-column oo_columns" t-ref="ooColumnsRef">
|
||||
<div class="pb-2 d-flex align-items-center oo_column" t-foreach="ooManager.columns" t-as="column" t-key="column.id" t-att-data-id="column.id" t-if="column.string.includes(ooManager.key)">
|
||||
<div class="o-checkbox form-check form-switch">
|
||||
<input type="checkbox" class="form-check-input" t-att-checked="column.visibility" t-on-click="onChangeVisibility" t-att-data-id="column.id"/>
|
||||
</div>
|
||||
<input type="text" class="form-control" t-att-value="column.string" disabled="true"/>
|
||||
<input type="number" class="form-control o_width_input" t-model="column.width" t-on-blur="onChangeColumns"/>
|
||||
<input type="color" class="o_color_input" t-model="column.color" t-on-blur="onChangeColumns"/>
|
||||
<div class="oo_sort_cell" t-if="!this.ooManager.key">
|
||||
<i class="btn fa fa-arrows"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-component='props.Renderer']" position="replace">
|
||||
<t t-component="props.Renderer"
|
||||
list="model.root"
|
||||
activeActions="activeActions"
|
||||
archInfo="archInfo"
|
||||
allowSelectors="props.allowSelectors"
|
||||
editable="editable"
|
||||
onOpenFormView="onOpenFormView"
|
||||
openRecord.bind="openRecord"
|
||||
noContentHelp="props.info.noContentHelp"
|
||||
onAdd.bind="createRecord"
|
||||
onOptionalFieldsChanged.bind="onOptionalFieldsChanged"
|
||||
evalViewModifier.bind="evalViewModifier"
|
||||
ooManagerColumns="ooManager.columns"
|
||||
ooManagerFilter="ooManager.filter"
|
||||
ooManagerSerialNum="ooManager.serial_num"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -0,0 +1,147 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
import {loadJS, loadCSS} from "@web/core/assets";
|
||||
import {ListRendererCust} from "@tree_view_advanced_filter/tree_view_advanced_filter/tree"
|
||||
|
||||
patch(ListRenderer.prototype, {
|
||||
setup() {
|
||||
super.setup();
|
||||
if(this.isX2Many) {
|
||||
this.props.ooManagerSerialNum = true;
|
||||
}
|
||||
},
|
||||
|
||||
getActiveColumns(list) {
|
||||
if (this.props.ooManagerColumns) {
|
||||
const columns = this.allColumns.filter((col) => {
|
||||
if (list.isGrouped && col.widget === "handle") {
|
||||
return false; // no handle column if the list is grouped
|
||||
}
|
||||
const mColumn = this.props.ooManagerColumns.find(item => item.id === col.id)
|
||||
if (mColumn) {
|
||||
return mColumn.visibility;
|
||||
}
|
||||
if (col.optional && !this.optionalActiveFields[col.name]) {
|
||||
return false;
|
||||
}
|
||||
if (this.evalColumnInvisible(col.column_invisible)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
columns.sort((x, y) => {
|
||||
const seqX = this.props.ooManagerColumns.find(item => item.id === x.id)?.seq || 0;
|
||||
const seqY = this.props.ooManagerColumns.find(item => item.id === y.id)?.seq || 0;
|
||||
return seqX - seqY;
|
||||
});
|
||||
|
||||
return columns
|
||||
|
||||
} else {
|
||||
return super.getActiveColumns(list);
|
||||
}
|
||||
},
|
||||
|
||||
freezeColumnWidths() {
|
||||
super.freezeColumnWidths();
|
||||
const table = this.tableRef.el;
|
||||
const headers = [...table.querySelectorAll("thead th:not(.o_list_actions_header)")];
|
||||
|
||||
headers.forEach((th, index) => {
|
||||
th.style.minWidth = `${Math.floor(this.columnWidths[index])}px`;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
* @param allowedWidth
|
||||
* @returns {*}
|
||||
*/
|
||||
computeColumnWidthsFromContent(allowedWidth) {
|
||||
const columnWidths = super.computeColumnWidthsFromContent(allowedWidth);
|
||||
if (!this.props.ooManagerColumns) return columnWidths;
|
||||
const table = this.tableRef.el;
|
||||
|
||||
// Toggle a className used to remove style that could interfere with the ideal width
|
||||
// computation algorithm (e.g. prevent text fields from being wrapped during the
|
||||
// computation, to prevent them from being completely crushed)
|
||||
table.classList.add("o_list_computing_widths");
|
||||
|
||||
const headers = [...table.querySelectorAll("thead th")];
|
||||
|
||||
headers.forEach((th, index) => {
|
||||
const id = th.getAttribute('data-id');
|
||||
const mColumn = this.props.ooManagerColumns.find(item => item.id === id)
|
||||
if (mColumn && mColumn.width) {
|
||||
columnWidths[index] = mColumn.width;
|
||||
}
|
||||
});
|
||||
|
||||
// We are no longer computing widths, so restore the normal style
|
||||
table.classList.remove("o_list_computing_widths");
|
||||
return columnWidths;
|
||||
},
|
||||
|
||||
/**
|
||||
* 样式
|
||||
* @param column
|
||||
* @returns {string}
|
||||
*/
|
||||
getColumnStyle(column) {
|
||||
if (!this.props.ooManagerColumns) return '';
|
||||
const mColumn = this.props.ooManagerColumns.find(item => item.id === column.id);
|
||||
if (mColumn && mColumn.color) {
|
||||
return 'color: ' + mColumn.color;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
_renderSearchPanel: async function () {
|
||||
if (this.isX2Many) {
|
||||
return ListRendererCust._renderSearchPanel.call(this);
|
||||
}
|
||||
if (!this.props.archInfo.advanced_filter) {
|
||||
$('.o_filter_box').remove();
|
||||
} else {
|
||||
await loadJS("/tree_view_advanced_filter/static/src/libs/daterangepicker.min.js");
|
||||
await loadCSS("/tree_view_advanced_filter/static/src/libs/daterangepicker.css");
|
||||
await loadJS("/tree_view_advanced_filter/static/src/libs/moment/moment.min.js");
|
||||
var List = this.props.list;
|
||||
const bm_params = List.model.__bm_load_params__;
|
||||
const rootRef = this.rootRef.el
|
||||
const tableRef = this.tableRef.el;
|
||||
tableRef.removeAttribute('style')
|
||||
const columns = this.getActiveColumns(this.props.list);
|
||||
|
||||
var $tr1 = $('<tr>', {class: 'o_filter_box'}).append(columns.map(columns => this._renderHeaderCellSearch(columns)));
|
||||
// 添加行号占位td
|
||||
$tr1.prepend($('<td>').addClass('web_list_num'));
|
||||
if (this.hasSelectors) {
|
||||
$tr1.prepend($('<td>').addClass('o_list_record_selector'));
|
||||
}
|
||||
|
||||
if (this.isStudioEditable || this.displayOptionalFields) {
|
||||
$tr1.append($('<td>').addClass('o_list_record_selector'));
|
||||
}
|
||||
|
||||
if ($(tableRef).find('.search_td').length) {
|
||||
$(tableRef).find('.search_td').parent().replaceWith($tr1)
|
||||
} else {
|
||||
$tr1.insertAfter($(tableRef).find('tr')[0]);
|
||||
}
|
||||
|
||||
rootRef.querySelectorAll('thead tr td.search_td input').forEach((a) => a.addEventListener('keyup', this._onfilter.bind(this)));
|
||||
rootRef.querySelectorAll('.search_button').forEach((a) => a.addEventListener('click', this._onSearch.bind(this)));
|
||||
rootRef.querySelectorAll('.remove_button').forEach((a) => a.addEventListener('click', this._onRemove.bind(this)));
|
||||
rootRef.querySelectorAll('thead tr td').forEach((a) => a.addEventListener('keypress', this._onKeyPress.bind(this)));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
ListRenderer.props.push('ooManagerColumns?')
|
||||
ListRenderer.props.push('ooManagerFilter?')
|
||||
ListRenderer.props.push('ooManagerSerialNum?')
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-inherit="web.ListRenderer" t-inherit-mode="extension">
|
||||
<xpath expr="//th[@t-att-data-name='column.name']" position="attributes">
|
||||
<attribute name="t-att-data-id">column.id</attribute>
|
||||
<attribute name="t-att-style">getColumnStyle(column)</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//thead//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<th class="list-number">#</th>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//tfoot//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<td/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-inherit="web.ListRenderer.RecordRow" t-inherit-mode="extension">
|
||||
<xpath expr="//td[@t-att-name='column.name']" position="attributes">
|
||||
<attribute name="t-att-style">getColumnStyle(column)</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<t t-set="num" t-value="(record_index + 1) + list.offset"/>
|
||||
<td t-esc="num" t-att-data-tooltip="num" class="cursor-pointer"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-inherit="web.ListRenderer.Rows" t-inherit-mode="extension">
|
||||
<xpath expr="//tr[@t-foreach='getEmptyRowIds']//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<td/>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<td/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-inherit="web.ListRenderer.GroupRow" t-inherit-mode="extension">
|
||||
<xpath expr="//t[@t-if='numSwitch']" position="replace">
|
||||
<t t-if="props.ooManagerSerialNum">
|
||||
<t t-set="num" t-value="(group_index + 1) + list.offset"/>
|
||||
<td t-esc="num" t-att-data-tooltip="num" class="cursor-pointer"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -54,7 +54,7 @@
|
||||
<t t-name="preview_easy.Many2OneFieldPreview" owl="1">
|
||||
<t t-set="editable" t-value="!props.readonly"/>
|
||||
<t t-set="file" t-value="getFile()"/>
|
||||
<t t-if="file.name">
|
||||
<t t-if="file and file.name">
|
||||
<!-- 预览按钮 -->
|
||||
<t t-if="props.previewType and props.previewType === 'button'">
|
||||
<button class="btn btn-secondary o_attach" t-on-click.stop="() => this.preview_Obj()" data-tooltip="Attach">
|
||||
|
||||
@@ -199,9 +199,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
if record_id:
|
||||
# 申请人自动匹配逻辑
|
||||
if is_automatic:
|
||||
department_domain = ['|',
|
||||
('department_id', '=', record_id.department_id.id),
|
||||
('department_ids', 'in', record_id.department_id.id)]
|
||||
department_domain = ['|', ('department_id', '=', record_id.department_id.id), ('department_ids', 'in', record_id.department_id.id)]
|
||||
elif is_automatic_company or is_automatic_group:
|
||||
applicant_field = None
|
||||
for field_name in ['user_id', 'users_id']:
|
||||
@@ -211,52 +209,31 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
break
|
||||
if applicant_field and hasattr(applicant_field, 'company_id'):
|
||||
if is_automatic_company:
|
||||
company_departments = self.env['hr.department'].search([
|
||||
('company_id', '=', applicant_field.company_id.id)
|
||||
]).ids
|
||||
department_domain = ['|',
|
||||
('department_id', 'in', company_departments),
|
||||
('department_ids', 'in', company_departments)]
|
||||
company_departments = self.env['hr.department'].search([('company_id', '=', applicant_field.company_id.id)]).ids
|
||||
department_domain = ['|', ('department_id', 'in', company_departments), ('department_ids', 'in', company_departments)]
|
||||
elif is_automatic_group:
|
||||
parent_company = applicant_field.company_id.parent_id
|
||||
group_departments = self.env['hr.department'].search([
|
||||
('company_id', 'child_of', parent_company.id)
|
||||
]).ids if parent_company else []
|
||||
department_domain = ['|',
|
||||
('department_id', 'in', group_departments),
|
||||
('department_ids', 'in', group_departments)]
|
||||
group_departments = self.env['hr.department'].search([('company_id', 'child_of', parent_company.id)]).ids if parent_company else []
|
||||
department_domain = ['|', ('department_id', 'in', group_departments), ('department_ids', 'in', group_departments)]
|
||||
# 登录人自动匹配逻辑
|
||||
elif is_logged_by:
|
||||
department_domain = ['|',
|
||||
('department_id', '=', self.env.user.department_id.id),
|
||||
('department_ids', 'in', self.env.user.department_id.id)]
|
||||
department_domain = ['|', ('department_id', '=', self.env.user.department_id.id), ('department_ids', 'in', self.env.user.department_id.id)]
|
||||
elif is_logged_company:
|
||||
company_departments = self.env['hr.department'].search([
|
||||
('company_id', '=', self.env.user.company_id.id)
|
||||
]).ids
|
||||
department_domain = ['|',
|
||||
('department_id', 'in', company_departments),
|
||||
('department_ids', 'in', company_departments)]
|
||||
company_departments = self.env['hr.department'].search([('company_id', '=', self.env.user.company_id.id)]).ids
|
||||
department_domain = ['|', ('department_id', 'in', company_departments), ('department_ids', 'in', company_departments)]
|
||||
elif is_logged_group:
|
||||
parent_company = self.env.user.company_id.parent_id
|
||||
group_departments = self.env['hr.department'].search([
|
||||
('company_id', 'child_of', parent_company.id)
|
||||
]).ids if parent_company else []
|
||||
department_domain = ['|',
|
||||
('department_id', 'in', group_departments),
|
||||
group_departments = self.env['hr.department'].search([('company_id', 'child_of', parent_company.id)]).ids if parent_company else []
|
||||
department_domain = ['|',('department_id', 'in', group_departments),
|
||||
('department_ids', 'in', group_departments)]
|
||||
# 角色筛选
|
||||
if link_users_id:
|
||||
role_domain = ['|',
|
||||
('user_role_id', '=', link_users_id.id),
|
||||
('user_role_ids', 'in', link_users_id.id)]
|
||||
role_domain = ['|', ('user_role_id', '=', link_users_id.id), ('user_role_ids', 'in', link_users_id.id)]
|
||||
company_domain = [('company_id', '=', self.env.user.company_id.id)]
|
||||
domain = role_domain + company_domain + department_domain
|
||||
return self.env['hr.employee'].sudo().search(domain)
|
||||
elif link_users_group_ids:
|
||||
role_domain = ['|',
|
||||
('user_role_id', 'in', link_users_group_ids.user_role_ids.ids),
|
||||
('user_role_ids', 'in', link_users_group_ids.user_role_ids.ids)]
|
||||
role_domain = ['|', ('user_role_id', 'in', link_users_group_ids.user_role_ids.ids), ('user_role_ids', 'in', link_users_group_ids.user_role_ids.ids)]
|
||||
company_domain = [('company_id', '=', self.env.user.company_id.id)]
|
||||
domain = role_domain + company_domain + department_domain
|
||||
return self.env['hr.employee'].sudo().search(domain)
|
||||
|
||||
@@ -14,6 +14,17 @@ class AppletAttendance(Controller):
|
||||
小程序考勤接口
|
||||
"""
|
||||
|
||||
@http.route('/ro/base/user/login/v1', type='http', auth="public", csrf=False, cors='*')
|
||||
def ro_base_user_login_v1(self, **kw):
|
||||
password = kw.get('password')
|
||||
login = kw.get('login')
|
||||
uid = request.session.authenticate(request.env.cr.dbname, login, password)
|
||||
user_id = request.env['res.users'].sudo().browse(uid)
|
||||
employee_id = user_id.with_company(user_id.company_id.id).employee_id
|
||||
data = {'name': employee_id.name, 'id': user_id.id}
|
||||
return_data = {'data': data, 'code': 200, 'message': ''}
|
||||
return json.dumps(return_data)
|
||||
|
||||
@route('/yuthon/att/today', methods=['POST'], type='http', auth='none', cors='*', csrf=False)
|
||||
def apple_yuthon_att_today(self, **kw):
|
||||
"""
|
||||
@@ -55,13 +66,15 @@ class AppletAttendance(Controller):
|
||||
return json.dumps(return_data)
|
||||
att_longitude = kw['att_longitude'] # 打卡经度
|
||||
att_latitude = kw['att_latitude'] # 打卡纬度
|
||||
longitude = address_id.longitude # 要求经度
|
||||
latitude = address_id.latitude # 要求纬度]
|
||||
longitude = kw['att_longitude'] # 要求经度
|
||||
# longitude = address_id.longitude # 要求经度
|
||||
latitude = kw['att_latitude'] # 要求纬度
|
||||
# latitude = address_id.latitude # 要求纬度
|
||||
if not att_longitude or not att_latitude:
|
||||
return_data = {
|
||||
'data': {"message": "经纬度必填", 'state': 'no', 'state_result': '超出范围'},
|
||||
'check_in': '未签到',
|
||||
'check_out':'未签到',
|
||||
'check_out': '未签到',
|
||||
'group_id': group_id,
|
||||
'code': '200',
|
||||
'message': 'OK',
|
||||
@@ -119,8 +132,8 @@ class AppletAttendance(Controller):
|
||||
check_in_str = check_in.strftime('%H:%M:%S') if check_in else ' '
|
||||
check_out_str = check_out.strftime('%H:%M:%S') if check_out else ' '
|
||||
# 构建带样式的富文本
|
||||
check_in_html = f'<p style="color:{get_status_color(check_in_status)}">{check_in_str} {check_in_status}</p>'
|
||||
check_out_html = f'<p style="color:{get_status_color(check_out_status)}">{check_out_str} {check_out_status}</p>'
|
||||
check_in_html = f'<p style="color:{get_status_color(check_in_status)}">{check_in_str}</p>'
|
||||
check_out_html = f'<p style="color:{get_status_color(check_out_status)}">{check_out_str}</p>'
|
||||
return_data = {
|
||||
'data': {
|
||||
'location': '%s' % address_id.address_name,
|
||||
@@ -129,7 +142,9 @@ class AppletAttendance(Controller):
|
||||
'class': f'{attendance_class}{start_datetime}/{end_datetime}',
|
||||
'state_result': state_result,
|
||||
'check_in': check_in_html,
|
||||
'check_in_status': check_in_status,
|
||||
'check_out': check_out_html,
|
||||
'check_out_status': check_out_status,
|
||||
},
|
||||
'code': '200',
|
||||
'message': 'OK',
|
||||
@@ -151,22 +166,17 @@ class AppletAttendance(Controller):
|
||||
小程序创建打卡记录
|
||||
:return:
|
||||
"""
|
||||
user_id = int(kw.get('id'))
|
||||
employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('user_id', '=', user_id.id)])
|
||||
recog_time_str = kw.get('recog_time_str')
|
||||
location_title = kw.get('location_title')
|
||||
checkin_time = datetime.strptime(recog_time_str, "%Y-%m-%d %H:%M:%S")
|
||||
user_id = kw.get('user_id')
|
||||
employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('user_id', '=', user_id)])
|
||||
if employee_id:
|
||||
request.env(user=SUPERUSER_ID)["hr.attendance.detail"].create({
|
||||
'employee_id': employee_id.id, # 员工
|
||||
'checkin_time': checkin_time, # 打卡时间
|
||||
'source': 'mini_programs', # 打卡来源
|
||||
'location_title': location_title, # 打卡地点
|
||||
'employee_id': employee_id.id,
|
||||
'checkin_time': fields.Datetime.now(),
|
||||
'source': 'mini_programs',
|
||||
})
|
||||
return_data = {
|
||||
'code': '200',
|
||||
'message': '推送成功',
|
||||
}
|
||||
return_data = {'code': '200', 'message': '推送成功'}
|
||||
else:
|
||||
return_data = {'code': '200', 'message': '未识别到员工'}
|
||||
return json.dumps(return_data)
|
||||
|
||||
@route('/yuthon/app/att', methods=['POST'], type='http', auth='none', csrf=False)
|
||||
@@ -216,15 +226,14 @@ class AppletAttendance(Controller):
|
||||
"""
|
||||
user_id = int(kw['user_id'])
|
||||
month = kw['selected_month'] # 2015-01
|
||||
year = month[0:4]
|
||||
month = month[-2:]
|
||||
year = int(month[0:4])
|
||||
month = int(month[-2:])
|
||||
# 当月日期范围
|
||||
current_month_first = datetime(year, month, 1)
|
||||
if month == 12:
|
||||
current_month_last = datetime(year + 1, 1, 1) - timedelta(days=1)
|
||||
else:
|
||||
current_month_last = datetime(year, month + 1, 1) - timedelta(days=1)
|
||||
|
||||
calendar_leaves = request.env(user=SUPERUSER_ID)['resource.calendar.leaves'].search([("calendar_id", "=", "行政考勤工作日")]) # 少一个search
|
||||
# 本月的节假日
|
||||
holiday_data = self.get_holiday_data(current_month_first.date(), current_month_last.date())
|
||||
@@ -369,6 +378,7 @@ class AppletAttendance(Controller):
|
||||
|
||||
|
||||
# 水电表接口
|
||||
|
||||
@route('/yuthon/meter/reading', methods=['POST'], type='http', auth='none', cors='*', csrf=False)
|
||||
def yuthon_meter_reading(self, **kw):
|
||||
"""
|
||||
@@ -384,35 +394,36 @@ class AppletAttendance(Controller):
|
||||
}
|
||||
"""
|
||||
_logger.info("----------------/yuthon/meter/reading---------接口收到响应-------------------------------")
|
||||
electric_records = request.env(user=SUPERUSER_ID)['property.electric.reading'].search([('reading_type', '=', '待抄')])
|
||||
water_records = request.env(user=SUPERUSER_ID)['property.water.reading'].search([('reading_type', '=', '待抄')])
|
||||
electric_records = request.env(user=SUPERUSER_ID)['property.electric.reading'].search([('reading_state', '=', 'wait')])
|
||||
water_records = request.env(user=SUPERUSER_ID)['property.water.reading'].search([('reading_state', '=', 'wait')])
|
||||
result_list = []
|
||||
# 处理电表记录
|
||||
for record in electric_records:
|
||||
record_data = {
|
||||
'code': record.property_id.code,
|
||||
'code': record.code,
|
||||
'last_dosage': record.last_dosage,
|
||||
'current_meter': record.current_meter,
|
||||
'dosage': record.dosage,
|
||||
'employee_name': record.employee_id.name,
|
||||
'employee_name': record.employee_ids[0].name,
|
||||
'meter_type': 'electric', # 添加仪表类型
|
||||
|
||||
}
|
||||
result_list.append(record_data)
|
||||
# 处理水表记录
|
||||
for record in water_records:
|
||||
record_data = {
|
||||
'code': record.property_id.code,
|
||||
'code': record.code,
|
||||
'last_dosage': record.last_dosage,
|
||||
'current_meter': record.current_meter,
|
||||
'dosage': record.dosage,
|
||||
'employee_list': record.employee_id.name,
|
||||
'employee_list': record.employee_ids[0].name,
|
||||
'meter_type': 'water',
|
||||
}
|
||||
result_list.append(record_data)
|
||||
return_data = {
|
||||
'data': result_list,
|
||||
'code': '200',
|
||||
'message': 'OK',
|
||||
'data': result_list,
|
||||
}
|
||||
return json.dumps(return_data)
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ class PropertyLeaseContract(models.Model):
|
||||
contact = fields.Char(related='lessee_id.contact', string="联系人")
|
||||
phone = fields.Char(related='lessee_id.phone', string="联系电话")
|
||||
email = fields.Char(related='lessee_id.email', string="电子邮箱")
|
||||
card = fields.Char(related='lessee_id.card', string="身份证号")
|
||||
invoicing_type = fields.Selection([('spot', '专票'), ('cape', '普票')], related='lessee_id.invoicing_type', string="开票类型")
|
||||
rental_purposes = fields.Many2one('yuthon.rental.purpose', string="出租用途")
|
||||
invoicing_begins = fields.Char(related='lessee_id.invoicing_begins', string="开票抬头")
|
||||
|
||||
@@ -28,15 +28,15 @@
|
||||
string="生成租金费用" invisible="1"/>
|
||||
<button name="action_generate_administrative_expenses" class="oe_link btn btn-primary" type="object"
|
||||
string="生成管理费用" invisible="1"/>
|
||||
<button name="action_copy_record1" type="object" string="拆分"/>
|
||||
<!-- <button name="action_copy_record1" type="object" string="拆分"/>-->
|
||||
</header>
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="新建" bg_color="text-bg-success"
|
||||
invisible="condition != 'new'"/>
|
||||
<widget name="web_ribbon" title="新建" bg_color="text-bg-success"
|
||||
invisible="condition != 'new'"/>
|
||||
<widget name="web_ribbon" title="审批" bg_color="text-bg-success"
|
||||
invisible="condition != 'approval'"/>
|
||||
invisible="condition != 'approval'"/>
|
||||
<widget name="web_ribbon" title="作废" bg_color="text-bg-danger"
|
||||
invisible="condition != 'cancel'"/>
|
||||
invisible="condition != 'cancel'"/>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="code" readonly="1" string="流水号:"/>
|
||||
@@ -47,7 +47,7 @@
|
||||
<field name="split_context" invisible="not is_split" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<div class="col-12 text-center">
|
||||
<div class="col-12 text-center">
|
||||
<h1>
|
||||
<field name="name_title" readonly="1"/>
|
||||
</h1>
|
||||
@@ -88,7 +88,8 @@
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="物业列表">
|
||||
<button name="choose_property_button" string="批量增加物业" type="object" class="btn-primary"/>
|
||||
<button name="choose_property_button" string="批量增加物业" type="object"
|
||||
class="btn-primary"/>
|
||||
<field name="lease_ids" string=" ">
|
||||
<tree editable="bottom">
|
||||
<field name="lease_id" column_invisible="1"/>
|
||||
@@ -104,7 +105,7 @@
|
||||
<group>
|
||||
<field name="license_id" widget="preview_many2one"/>
|
||||
<field name="legal_entity_id" widget="preview_many2one"/>
|
||||
<field name="handover_time" widget="preview_many2one"/>
|
||||
<field name="handover_time"/>
|
||||
<field name="lease_contract" widget="preview_many2one"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -115,7 +116,7 @@
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="承租方个人信息">
|
||||
<page string="承租方信息" invisible="1">
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="invoicing_type"/>
|
||||
@@ -127,6 +128,7 @@
|
||||
<field name="contact"/>
|
||||
<field name="phone"/>
|
||||
<field name="email"/>
|
||||
<field name="card"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
@@ -212,7 +214,7 @@
|
||||
<field name="is_mange" invisible="1"/>
|
||||
<field name="performance_bonds_write" invisible="1"/>
|
||||
<label for="first_years_begin" invisible="is_less_than_2"/>
|
||||
<div class="d-inline-flex w-100" invisible="is_less_than_2">
|
||||
<div class="d-inline-flex w-100" invisible="is_less_than_2">
|
||||
<field name="first_years_begin" string="自第" class="me-2"
|
||||
style="max-width: 3rem !important;"/>年开始,每
|
||||
<field name="increments_every_few_years" class="me-2"
|
||||
@@ -269,7 +271,7 @@
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="其他费用">
|
||||
<page string="其他费用">
|
||||
<field name="other_ids" string=" ">
|
||||
<tree editable="bottom">
|
||||
<field name="other_id" column_invisible="1"/>
|
||||
@@ -328,7 +330,7 @@
|
||||
</notebook>
|
||||
<group col="4">
|
||||
<group>
|
||||
<field name="tax" readonly="1" force_save="1"/>
|
||||
<field name="tax" readonly="1" force_save="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="not_tax_amount" readonly="1" force_save="1"/>
|
||||
@@ -348,33 +350,33 @@
|
||||
<field name="name">property.lease.contract.tree</field>
|
||||
<field name="model">property.lease.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree create="false" string="物业合同管理" limit="20" >
|
||||
<header>
|
||||
<!-- <button name="all_put_evaluation_plan" string="评估推送" type="object" class="btn btn-primary"/>-->
|
||||
<tree create="false" string="物业合同管理" limit="20">
|
||||
<header>
|
||||
<!-- <button name="all_put_evaluation_plan" string="评估推送" type="object" class="btn btn-primary"/>-->
|
||||
<button name="button_lease_extension" type="object" class="btn-primary" string="续租"/>
|
||||
<button name="button_lease_return" type="object" class="btn-primary" string="退租"/>
|
||||
<button name="button_lease_change" type="object" class="btn-primary" string="变更"/>
|
||||
<button name="action_copy_record1" type="object" string="拆分"/>
|
||||
</header>
|
||||
<button name="button_lease_change" type="object" class="btn-primary" string="变更"/>
|
||||
<!-- <button name="action_copy_record1" type="object" string="拆分"/>-->
|
||||
</header>
|
||||
<field name="name"/>
|
||||
<field name="contract_code" decoration-danger = "is_equal"/>
|
||||
<field name="contract_code" decoration-danger="is_equal"/>
|
||||
<field name="lessee_id"/>
|
||||
<field name="total_area"/>
|
||||
<field name="is_equal" column_invisible="1"/>
|
||||
<field name="deposit" decoration-success = "deposit_status == 'paid'"
|
||||
decoration-danger = "deposit_status == 'unpaid'" decoration-muted = "deposit_status == 'returned'"
|
||||
decoration-warning = "deposit_status == 'no_paid'"/>
|
||||
<field name="deposit" decoration-success="deposit_status == 'paid'"
|
||||
decoration-danger="deposit_status == 'unpaid'" decoration-muted="deposit_status == 'returned'"
|
||||
decoration-warning="deposit_status == 'no_paid'"/>
|
||||
<field name="rent"/>
|
||||
<field name="not_received" decoration-muted="comparison == 'equal'"
|
||||
decoration-danger = "comparison == 'outweigh'"
|
||||
decoration-success = "comparison == 'less'"/>
|
||||
decoration-danger="comparison == 'outweigh'"
|
||||
decoration-success="comparison == 'less'"/>
|
||||
<field name="comparison" column_invisible="1"/>
|
||||
<field name="percentage_damages"/>
|
||||
<field name="percentage_damages"/>
|
||||
<field name="total_receivable"/>
|
||||
<field name="term_start_time"/>
|
||||
<field name="term_end_time" decoration-info="end_comparison == 'blue'"
|
||||
decoration-danger = "end_comparison == 'red'"
|
||||
decoration-warning = "end_comparison == 'yellow'"/>
|
||||
decoration-danger="end_comparison == 'red'"
|
||||
decoration-warning="end_comparison == 'yellow'"/>
|
||||
<field name="actual_start_time"/>
|
||||
<field name="actual_end_time"/>
|
||||
<field name="end_comparison" column_invisible="1"/>
|
||||
@@ -382,9 +384,10 @@
|
||||
<field name="company_id" string="公司"/>
|
||||
<field name="admin_id" string="负责人"/>
|
||||
<field name="contact_state"/>
|
||||
<button name="put_evaluation_plan" type="object" class="btn-primary" string="评估推送" invisible="contact_state == 'ing'"/>
|
||||
<!-- <button name="button_lease_extension" type="object" class="btn-primary" string="续租"/>-->
|
||||
<!-- <button name="button_lease_return" type="object" class="btn-primary" string="退租"/>-->
|
||||
<button name="put_evaluation_plan" type="object" class="btn-primary" string="评估推送"
|
||||
invisible="contact_state == 'ing'"/>
|
||||
<!-- <button name="button_lease_extension" type="object" class="btn-primary" string="续租"/>-->
|
||||
<!-- <button name="button_lease_return" type="object" class="btn-primary" string="退租"/>-->
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -401,13 +404,13 @@
|
||||
</header>
|
||||
<sheet>
|
||||
<widget name="web_ribbon" title="待执行" bg_color="text-bg-success"
|
||||
invisible="condition != 'be_executed'"/>
|
||||
invisible="condition != 'be_executed'"/>
|
||||
<widget name="web_ribbon" title="已执行" bg_color="text-bg-success"
|
||||
invisible="condition != 'executed'"/>
|
||||
invisible="condition != 'executed'"/>
|
||||
<widget name="web_ribbon" title="已终止" bg_color="text-bg-success"
|
||||
invisible="condition != 'expired'"/>
|
||||
invisible="condition != 'expired'"/>
|
||||
<widget name="web_ribbon" title="提前终止" bg_color="text-bg-danger"
|
||||
invisible="condition != 'advance'"/>
|
||||
invisible="condition != 'advance'"/>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="code" readonly="1" string="流水号:"/>
|
||||
@@ -463,7 +466,8 @@
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="物业列表">
|
||||
<button name="choose_property_button" string="批量增加物业" type="object" class="btn-primary"/>
|
||||
<button name="choose_property_button" string="批量增加物业" type="object"
|
||||
class="btn-primary"/>
|
||||
<field name="lease_ids" string=" ">
|
||||
<tree editable="bottom" create="false" edit="false" delete="false">
|
||||
<field name="lease_id" column_invisible="1"/>
|
||||
@@ -480,7 +484,7 @@
|
||||
<group>
|
||||
<field name="license_id" widget="preview_many2one"/>
|
||||
<field name="legal_entity_id" widget="preview_many2one"/>
|
||||
<field name="handover_time" widget="preview_many2one"/>
|
||||
<field name="handover_time"/>
|
||||
<field name="lease_contract" widget="preview_many2one"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -491,7 +495,7 @@
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="承租方个人信息">
|
||||
<page string="承租方信息">
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="invoicing_type"/>
|
||||
@@ -536,7 +540,7 @@
|
||||
</group>
|
||||
<group col="2" string="租赁期限">
|
||||
<group>
|
||||
<label for="lease_term_year" />
|
||||
<label for="lease_term_year"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="lease_term_year"/>
|
||||
年
|
||||
@@ -545,10 +549,12 @@
|
||||
<field name="lease_term_day"/>
|
||||
日
|
||||
</div>
|
||||
<label for="term_start_time"/>
|
||||
<label for="term_start_time"/>
|
||||
<div class="d-inline-flex w-100">
|
||||
<field name="term_start_time" class="me-2" style="max-width: 11rem !important;"/>结束时间
|
||||
<field name="term_end_time" class="me-2" style="max-width: 11rem !important;" force_save="1"/>
|
||||
<field name="term_start_time" class="me-2" style="max-width: 11rem !important;"
|
||||
readonly="1"/>结束时间
|
||||
<field name="term_end_time" class="me-2" style="max-width: 11rem !important;"
|
||||
readonly="1" force_save="1"/>
|
||||
</div>
|
||||
<field name="actual_start_time" invisible="1"/>
|
||||
<field name="actual_end_time" invisible="1"/>
|
||||
@@ -642,7 +648,7 @@
|
||||
<field name="miscellaneous"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="租金明细">
|
||||
<page string="租金明细">
|
||||
<field name="breakdown_ids" string=" ">
|
||||
<tree editable="bottom" edit="false" delete="false" create="false">
|
||||
<field name="breakdown_id" column_invisible="1"/>
|
||||
@@ -712,9 +718,9 @@
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="4">
|
||||
<group col="4">
|
||||
<group>
|
||||
<field name="tax" readonly="1" force_save="1"/>
|
||||
<field name="tax" readonly="1" force_save="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="not_tax_amount" readonly="1" force_save="1"/>
|
||||
@@ -723,7 +729,8 @@
|
||||
<field name="first_year_rent" force_save="1" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="total_contract_receivables" style="font-size: 1.2rem; font-weight: bold;" readonly="1"/>
|
||||
<field name="total_contract_receivables" style="font-size: 1.2rem; font-weight: bold;"
|
||||
readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
@@ -744,7 +751,7 @@
|
||||
<field name="tenure_type"/>
|
||||
</searchpanel>
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="group_by_condition" context="{'group_by': 'condition'}"/>
|
||||
<filter name="group_by_condition" context="{'group_by': 'condition'}"/>
|
||||
<filter name="group_by_lessee_id" context="{'group_by': 'lessee_id'}"/>
|
||||
<filter name="group_by_company_id" context="{'group_by': 'company_id'}"/>
|
||||
<filter name="group_by_admin_id" context="{'group_by': 'admin_id'}"/>
|
||||
@@ -772,23 +779,23 @@
|
||||
</field>
|
||||
</record>
|
||||
<record id="yuthon_property_rented_area_report_search" model="ir.ui.view">
|
||||
<field name="name">yuthon.property.rented.area.report.search</field>
|
||||
<field name="model">property.lease.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="已租面积报表">
|
||||
<field name="admin_id"/>
|
||||
<field name="company_id"/>
|
||||
<field name="tenure_type"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="权属类型" name="group_by_tenure_type" context="{'group_by': 'tenure_type'}"/>
|
||||
</group>
|
||||
<searchpanel>
|
||||
<field name="company_id" enable_counters="1" />
|
||||
<field name="tenure_type" enable_counters="1" string="权属类型"/>
|
||||
<field name="precinct_id" string="所属片区" enable_counters="1"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
<field name="name">yuthon.property.rented.area.report.search</field>
|
||||
<field name="model">property.lease.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="已租面积报表">
|
||||
<field name="admin_id"/>
|
||||
<field name="company_id"/>
|
||||
<field name="tenure_type"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="权属类型" name="group_by_tenure_type" context="{'group_by': 'tenure_type'}"/>
|
||||
</group>
|
||||
<searchpanel>
|
||||
<field name="company_id" enable_counters="1"/>
|
||||
<field name="tenure_type" enable_counters="1" string="权属类型"/>
|
||||
<field name="precinct_id" string="所属片区" enable_counters="1"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="rented_area_report_action" model="ir.actions.act_window">
|
||||
<field name="name">已租面积报表</field>
|
||||
|
||||
@@ -89,15 +89,13 @@ class YuthonPayrollCommon(models.Model):
|
||||
formula_salary = "result = 0"
|
||||
if ins.name == '上月值班费':
|
||||
formula_salary = "result = 0"
|
||||
if ins.name == '年金(系数)':
|
||||
formula_salary = "result = 0"
|
||||
if ins.name == '六一儿童节福利费':
|
||||
formula_salary = "result = 0"
|
||||
if ins.name == '环境作业津贴':
|
||||
formula_salary = "result = 0"
|
||||
if ins.name == '质检员津贴':
|
||||
formula_salary = "result = 0"
|
||||
if ins.name == '工会会费' and ins.company_id.name in ['集团本部','天河物管']:
|
||||
if ins.name == '工会会费' and ins.company_id.name in ['集团本部', '天河物管']:
|
||||
formula_salary = "result = round((payslip.base_salary * 0.005), 2)"
|
||||
if ins.name == '工会会费' and ins.company_id.name == '天河粮储':
|
||||
formula_salary = "result = 20 if employee.user_role_id.name in ['总经理', '副总经理'] else \
|
||||
|
||||
Reference in New Issue
Block a user