Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@@ -9,6 +9,7 @@ import { localization } from "@web/core/l10n/localization";
|
||||
import {formatDate,formatDateTime} from "@web/core/l10n/dates";
|
||||
import {parseDateTime,parseDate,} from "@web/core/l10n/dates";
|
||||
import { renderToElement } from "@web/core/utils/render";
|
||||
import { session } from "@web/session";
|
||||
|
||||
export class Ksdashboardgraph extends Component{
|
||||
setup(){
|
||||
@@ -16,6 +17,7 @@ export class Ksdashboardgraph extends Component{
|
||||
this.actionService = useService("action");
|
||||
this._rpc = useService("rpc");
|
||||
this.state = useState({item_data:"",list_view_data:""})
|
||||
this.isAdmin = session.is_system;
|
||||
onMounted(() => this._update_view());
|
||||
onPatched(() => this.update_list_view());
|
||||
this.item = this.props.item
|
||||
|
||||
+62
-69
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="Ks_chart_list_container">
|
||||
<t t-if="item.ks_dashboard_item_type == 'ks_list_view'">
|
||||
<t t-call="ks_dashboard_ninja.Ksdashboardlistview"/>
|
||||
@@ -9,50 +8,46 @@
|
||||
<t t-call="Ks_gridstack_container"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="Ks_gridstack_container">
|
||||
<div class="grid-stack-item ks_chart_container ks_dashboarditem_id" t-att-id="chart_id" t-ref="ks_gridstack_container">
|
||||
<div class="grid-stack-item-content ks_dashboarditem_chart_container ks_dashboard_item_hover card shadow"
|
||||
t-att-title="ks_info">
|
||||
|
||||
<div class="p-3 py-3 d-flex flex-row align-items-center justify-content-between ">
|
||||
<div class="d-flex align-items-center">
|
||||
<h6 class="m-0 font-weight-bold h3 ks_chart_heading mr-3" t-att-title="ks_chart_title">
|
||||
<t t-esc="ks_chart_title"/>
|
||||
</h6>
|
||||
<!-- <div >-->
|
||||
<t t-if="ks_breadcrumb.length >= 1">
|
||||
<nav class="ks_breadcrumb">
|
||||
<t t-if="ks_breadcrumb.length >= 1">
|
||||
<nav class="ks_breadcrumb">
|
||||
<ul>
|
||||
<li class="d-none" t-att-id="'item'+'_'+'-1'">
|
||||
<span t-att-data-sequence = '-1' t-att-data-item-id="chart_id" t-on-click="ksOnDrillUp">
|
||||
<t t-esc="ks_chart_title"/>
|
||||
</span>
|
||||
<span t-att-data-sequence = '-1' t-att-data-item-id="chart_id" t-on-click="ksOnDrillUp">
|
||||
<t t-esc="ks_chart_title"/>
|
||||
</span>
|
||||
</li>
|
||||
<t t-foreach="ks_breadcrumb" t-as="chart_breadcrumb" t-key="chart_breadcrumb_index">
|
||||
<li class="d-none" t-att-id="chart_breadcrumb['name'] + '_' + chart_breadcrumb_index">
|
||||
<li class="d-none" t-att-id="chart_breadcrumb['name'] + '_' + chart_breadcrumb_index">
|
||||
<span t-att-data-sequence="chart_breadcrumb_index" t-att-data-item-id="chart_id" t-on-click="ksOnDrillUp">
|
||||
<t t-esc="chart_breadcrumb['name']"/>
|
||||
<t t-esc="chart_breadcrumb['name']"/>
|
||||
</span>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</nav>
|
||||
</t>
|
||||
</nav>
|
||||
</t>
|
||||
</div>
|
||||
<!-- </div>-->
|
||||
<img src="ks_dashboard_ninja/static/images/selected.svg" class="ks_img_display d-none"
|
||||
width="30"/>
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header ks_dashboard_item_header_hover chart_button_container d-md-flex d-none"
|
||||
t-att-data-item_id="chart_id">
|
||||
|
||||
<t t-if="ksIsDashboardManager">
|
||||
<button class="ks_dashboard_item_chart_info" title="More Info" type="button"
|
||||
t-att-data-item_id="chart_id" t-if="isAdmin">
|
||||
<t t-if="ksIsDashboardManager and isAdmin">
|
||||
<button class="ks_dashboard_item_chart_info" title="More Info" type="button"
|
||||
t-att-data-item-id="chart_id">
|
||||
<i class="fa fa-info-circle"/>
|
||||
</button>
|
||||
|
||||
<i class="fa fa-info-circle"/>
|
||||
</button>
|
||||
<t t-if="ks_dashboard_item_type != 'ks_map_view'">
|
||||
<div class="ks_chart_inner_buttons">
|
||||
<button title="Color Palette" data-bs-toggle="dropdown"
|
||||
@@ -76,8 +71,6 @@
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
<div class="ks_chart_inner_buttons">
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
class="ks_dashboard_item_action btn dropdown-toggle btn-xs" type="button"
|
||||
@@ -109,101 +102,103 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<button title="Quick Customize"
|
||||
class="ks_dashboard_quick_edit_action_popup btn d-sm-block d-none"
|
||||
type="button" t-att-data-item-id="chart_id">
|
||||
<i class="fa fa-pencil"/>
|
||||
</button>
|
||||
|
||||
<button class="ks_dashboard_item_customize d-block d-sm-none" title="Customize Item"
|
||||
type="button" t-att-data-item-id="chart_id">
|
||||
<i class="fa fa-pencil"/>
|
||||
</button>
|
||||
|
||||
<button class="ks_dashboard_item_delete" title="Remove Item" type="button">
|
||||
<i class="fa fa-times"/>
|
||||
</button>
|
||||
</t>
|
||||
<t t-if="ksIsUser">
|
||||
<div class="ks_chart_inner_buttons ks_dashboard_more_action"
|
||||
<div class="ks_chart_inner_buttons ks_dashboard_more_action"
|
||||
t-att-data-item-id="chart_id">
|
||||
<button title="Export Chart" data-bs-toggle="dropdown"
|
||||
<button title="Export Chart" data-bs-toggle="dropdown"
|
||||
class="ks_dashboard_item_action btn dropdown-toggle btn-xs o-no-caret btn"
|
||||
type="button"
|
||||
aria-expanded="true">
|
||||
<i class="fa fa-ellipsis-v"/>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right">
|
||||
<!--Dynamic Rendering-->
|
||||
<t t-call="ksMoreChartOptions"/>
|
||||
</div>
|
||||
<i class="fa fa-ellipsis-v"/>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right">
|
||||
<!--Dynamic Rendering-->
|
||||
<t t-call="ksMoreChartOptions"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
<div class="ks_chart_inner_buttons dropdown">
|
||||
<button title="Info" data-bs-toggle="dropdown"
|
||||
<button title="Info" data-bs-toggle="dropdown"
|
||||
class="ks_item_description btn dropdown-toggle btn-xs o-no-caret btn"
|
||||
type="button"
|
||||
t-att-style="'color:'+ ks_rgba_button_color + ';'"
|
||||
aria-expanded="true">
|
||||
<i class="fa fa-book"/>
|
||||
</button>
|
||||
<i class="fa fa-book"/>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right" style="width:20rem">
|
||||
<!--Dynamic Rendering-->
|
||||
<!--Dynamic Rendering-->
|
||||
<div class="ks_chart_export_menu">
|
||||
<div class="ks_chart_export_menu_header" style="margin-left:-10px">
|
||||
<span>Info</span>
|
||||
</div>
|
||||
<div class="ks_chart_export_menu_header" style="margin-left:-10px">
|
||||
<span>Info</span>
|
||||
</div>
|
||||
<div class="ks_info" style="margin-left:10px">
|
||||
<span>Company: <t t-esc="ks_company"/></span>
|
||||
</div>
|
||||
<span>Company:
|
||||
<t t-esc="ks_company"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="ks_info" style="margin-left:10px">
|
||||
<t t-if="ks_info">
|
||||
<t t-foreach="ks_info" t-as="ks_description" t-key="ks_description_index">
|
||||
<span><t t-esc="ks_description"/></span>
|
||||
<br></br>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="ks_info">
|
||||
<t t-foreach="ks_info" t-as="ks_description" t-key="ks_description_index">
|
||||
<span>
|
||||
<t t-esc="ks_description"/>
|
||||
</span>
|
||||
<br></br>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<t t-if="ksIsDashboardManager">
|
||||
<div class="dropdown d-md-none dn-setting-panel">
|
||||
<button class="btn btn-secondary border-0" type="button" id="dropdownSettingButton"
|
||||
<button class="btn btn-secondary border-0" type="button" id="dropdownSettingButton"
|
||||
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fa fa-cog"></i>
|
||||
</button>
|
||||
|
||||
<i class="fa fa-cog"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownSettingButton">
|
||||
<t t-if="ks_show_records & ks_query_type=='custom'">
|
||||
<a class="dropdown-item ks_dashboard_item_chart_info ks_info_display"
|
||||
<t t-if="ks_show_records & ks_query_type=='custom'">
|
||||
<a class="dropdown-item ks_dashboard_item_chart_info ks_info_display"
|
||||
t-att-data-item-id="chart_id">
|
||||
<i class="fa fa-info-circle"/>
|
||||
<i class="fa fa-info-circle"/>
|
||||
More Info
|
||||
</a>
|
||||
</t>
|
||||
</a>
|
||||
</t>
|
||||
<a class="dropdown-item ks_dashboard_item_customize" t-att-data-item-id="chart_id">
|
||||
<i class="fa fa-pencil"></i>
|
||||
<i class="fa fa-pencil"></i>
|
||||
Customize Item
|
||||
</a>
|
||||
|
||||
</a>
|
||||
<a class="dropdown-item ks_dashboard_item_delete">
|
||||
<i class="fa fa-times"></i>
|
||||
<i class="fa fa-times"></i>
|
||||
Remove Item
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<t t-if="ks_ai_analysis">
|
||||
<div class="ks_ai_explain_body">
|
||||
<div class="card-body ks_chart_card_body"></div>
|
||||
<div class="ks_ai_explanation">
|
||||
<p><t t-esc="ks_ai_analysis_1"/></p>
|
||||
<p><t t-esc="ks_ai_analysis_2"/></p>
|
||||
<p>
|
||||
<t t-esc="ks_ai_analysis_1"/>
|
||||
</p>
|
||||
<p>
|
||||
<t t-esc="ks_ai_analysis_2"/>
|
||||
</p>
|
||||
</div>
|
||||
<div class="ks_speaker" t-on-click="props.ks_speak">
|
||||
<span class="fa fa-volume-up"/>
|
||||
@@ -217,7 +212,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="ksMoreChartOptions">
|
||||
<div class="ks_chart_export_menu">
|
||||
<div class="ks_chart_export_menu_header">
|
||||
@@ -233,7 +227,6 @@
|
||||
<i class="fa fa-file-code-o"/>
|
||||
<span>Export to CSV</span>
|
||||
</div>
|
||||
|
||||
<div t-att-data-chart-id="chart_id" class="ks_chart_pdf_export ks_chart_export_menu_item">
|
||||
<i class="fa fa-file-pdf-o"/>
|
||||
<span>Save as PDF</span>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { formatInteger } from "@web/views/fields/formatters";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
|
||||
import { session } from "@web/session";
|
||||
export class Ksdashboardkpiview extends Component{
|
||||
file_type_magic_word= {'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'}
|
||||
setup(){
|
||||
@@ -15,6 +15,7 @@ export class Ksdashboardkpiview extends Component{
|
||||
this.actionService = useService("action");
|
||||
this.ks_kpi = useRef('ks_kpi')
|
||||
this.state = useState({item_info_kpi1:{},item_info_kpi2:{},item_info_kpi3:{}})
|
||||
this.isAdmin = session.is_system;
|
||||
onMounted(() => this._update_view());
|
||||
this.item = this.props.item
|
||||
this.ks_dashboard_data = this.props.dashboard_data
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
<img src="ks_dashboard_ninja/static/images/selected.svg" class="ks_img_display d-none" width="30"/>
|
||||
<!---->
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header_l6 ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="state.item_info_kpi1.item.id">
|
||||
t-att-data-item_id="state.item_info_kpi1.item.id" t-if="isAdmin">
|
||||
<t t-if="state.item_info_kpi1.item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
@@ -305,7 +305,7 @@
|
||||
</t>
|
||||
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header_l6 ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="state.item_info_kpi2.item.id">
|
||||
t-att-data-item_id="state.item_info_kpi2.item.id" t-if="isAdmin">
|
||||
<t t-if="state.item_info_kpi2.item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
@@ -489,7 +489,7 @@
|
||||
</t>
|
||||
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header_l6 ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="state.item_info_kpi3.item.id">
|
||||
t-att-data-item_id="state.item_info_kpi3.item.id" t-if="isAdmin">
|
||||
<t t-if="state.item_info_kpi3.item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@
|
||||
<!-- -->
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header ks_dashboard_item_header_hover chart_button_container d-md-flex d-none"
|
||||
t-att-data-item_id="item_id">
|
||||
t-att-data-item_id="item_id" >
|
||||
<t t-if="ksIsDashboardManager">
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown" t-att-data-item-id="item_id"
|
||||
class="ks_dashboard_item_action btn dropdown-toggle btn-xs" type="button"
|
||||
|
||||
+2
-1
@@ -5,7 +5,7 @@ import { loadBundle } from "@web/core/assets";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { jsonrpc } from "@web/core/network/rpc_service";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
|
||||
import { session } from "@web/session";
|
||||
export class Ksdashboardtile extends Component{
|
||||
file_type_magic_word= {'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'}
|
||||
|
||||
@@ -17,6 +17,7 @@ export class Ksdashboardtile extends Component{
|
||||
this.ks_container_class = 'grid-stack-item';
|
||||
this.ks_inner_container_class = 'grid-stack-item-content';
|
||||
this.state = useState({data_count:""})
|
||||
this.isAdmin = session.is_system;
|
||||
this.item = this.props.item
|
||||
this.file_type_magic_word= {'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'}
|
||||
this.ks_dashboard_data = this.props.dashboard_data
|
||||
|
||||
+7
-7
@@ -33,7 +33,7 @@
|
||||
t-att-title="item.ks_info"
|
||||
t-att-id="item.id">
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="item.id">
|
||||
t-att-data-item_id="item.id" t-if="isAdmin">
|
||||
|
||||
<t t-if="item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
@@ -230,7 +230,7 @@
|
||||
</div>
|
||||
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header_l6 ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="item.id">
|
||||
t-att-data-item_id="item.id" t-if="isAdmin">
|
||||
<t t-if="item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
@@ -383,7 +383,7 @@
|
||||
t-att-title="item.ks_info" t-att-id="item.id">
|
||||
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="item.id">
|
||||
t-att-data-item_id="item.id" t-if="isAdmin">
|
||||
<t t-if="item.ksIsDashboardManager">
|
||||
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
@@ -581,7 +581,7 @@
|
||||
|
||||
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header_l6 ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="item.id">
|
||||
t-att-data-item_id="item.id" t-if="isAdmin">
|
||||
<t t-if="item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
@@ -756,7 +756,7 @@
|
||||
|
||||
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header_l2 ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="item.id">
|
||||
t-att-data-item_id="item.id" t-if="isAdmin">
|
||||
|
||||
<t t-if="item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
@@ -933,7 +933,7 @@
|
||||
|
||||
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header_l6 ks_dashboard_item_header_hover"
|
||||
t-att-data-item_id="item.id">
|
||||
t-att-data-item_id="item.id" t-if="isAdmin">
|
||||
<t t-if="item.ksIsDashboardManager">
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
@@ -1074,7 +1074,7 @@
|
||||
<t t-name="ks_dashboard_item_layout_default">
|
||||
<div t-att-id="item.id" t-att-class="'ks_item_click ' + ks_container_class">
|
||||
<div class="ks_dashboard_item ks_dashboard_item_hover"
|
||||
t-att-style="style_main_body">
|
||||
t-att-style="style_main_body" t-if="isAdmin">
|
||||
<t t-if="item.ksIsDashboardManager">
|
||||
<div class="ks_dashboard_item_header ks_dashboard_item_header_hover">
|
||||
<button type="button" title="Customize Item" class="ks_dashboard_item_customize">
|
||||
|
||||
+2
-1
@@ -7,7 +7,7 @@ import { useService } from "@web/core/utils/hooks";
|
||||
import {Todoeditdialog,addtododialog} from "@ks_dashboard_ninja/components/ks_dashboard_to_do_item/editdialog";
|
||||
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
|
||||
import { session } from "@web/session";
|
||||
export class Ksdashboardtodo extends Component{
|
||||
setup(){
|
||||
super.setup();
|
||||
@@ -17,6 +17,7 @@ export class Ksdashboardtodo extends Component{
|
||||
this.item = this.props.item
|
||||
this.ks_dashboard_data = this.props.dashboard_data
|
||||
this.prepare_item();
|
||||
this.isAdmin = session.is_system;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+53
-72
@@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
|
||||
|
||||
<t t-name="Ksdashboardtodo">
|
||||
<t t-name="Ksdashboardtodo">
|
||||
<div class="grid-stack-item ks_dashboarditem_id" t-att-id="item_id">
|
||||
<div class="grid-stack-item-content ks_list_view_container ks_dashboard_item_hover card shadow"
|
||||
t-att-title="ks_info">
|
||||
@@ -16,10 +13,9 @@
|
||||
<t t-esc="ks_chart_title"/>
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
<!-- Dashboard Item Move/Copy Feature -->
|
||||
<div class="ks_dashboard_item_button_container ks_dropdown_container ks_dashboard_item_header ks_dashboard_item_header_hover chart_button_container d-md-flex d-none"
|
||||
t-att-data-item_id="item_id">
|
||||
t-att-data-item_id="item_id" t-if="isAdmin">
|
||||
<t t-if="ksIsDashboardManager">
|
||||
<button title="Move/Duplicate" data-bs-toggle="dropdown"
|
||||
t-att-data-item-id="item_id"
|
||||
@@ -39,7 +35,7 @@
|
||||
<option t-att-value="ks_dashboard['id']">
|
||||
<t t-esc="ks_dashboard['name']"/>
|
||||
</option>
|
||||
</t>
|
||||
</t>
|
||||
</select>
|
||||
</li>
|
||||
<li class="mt-3">
|
||||
@@ -58,7 +54,6 @@
|
||||
type="button" t-att-data-item-id="item_id">
|
||||
<i class="fa fa-pencil"/>
|
||||
</button>
|
||||
|
||||
<button class="ks_dashboard_item_customize d-block text-white d-sm-none"
|
||||
title="Customize Item"
|
||||
t-att-style="'color:'+ ks_rgba_button_color + ' !important' + ';'"
|
||||
@@ -73,77 +68,78 @@
|
||||
</t>
|
||||
<t t-if="ksIsUser">
|
||||
<div class="ks_chart_inner_buttons">
|
||||
<button title="Export List" data-bs-toggle="dropdown"
|
||||
<button title="Export List" data-bs-toggle="dropdown"
|
||||
class="ks_dashboard_item_action_export text-white btn dropdown-toggle btn-xs o-no-caret btn"
|
||||
t-att-style="'color:'+ ks_rgba_button_color + ' !important' + ';'"
|
||||
type="button"
|
||||
aria-expanded="true">
|
||||
<i class="fa fa-ellipsis-v"/>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right">
|
||||
<!--Dynamic Rendering-->
|
||||
<div class="ks_chart_export_menu">
|
||||
<div class="ks_chart_export_menu_header">
|
||||
<span>Export</span>
|
||||
</div>
|
||||
<div class="ks_chart_json_export ks_chart_export_menu_item"
|
||||
<i class="fa fa-ellipsis-v"/>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right">
|
||||
<!--Dynamic Rendering-->
|
||||
<div class="ks_chart_export_menu">
|
||||
<div class="ks_chart_export_menu_header">
|
||||
<span>Export</span>
|
||||
</div>
|
||||
<div class="ks_chart_json_export ks_chart_export_menu_item"
|
||||
t-att-data-item-id="item_id"
|
||||
data-format="chart_xls">
|
||||
<i class="fa fa-file-code-o"/>
|
||||
<span>Export Item</span>
|
||||
<i class="fa fa-file-code-o"/>
|
||||
<span>Export Item</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<div class="ks_chart_inner_buttons dropdown">
|
||||
<button title="Item description" data-bs-toggle="dropdown"
|
||||
<button title="Item description" data-bs-toggle="dropdown"
|
||||
class="ks_item_description btn dropdown-toggle btn-xs o-no-caret btn"
|
||||
type="button"
|
||||
t-att-style="'color:'+ ks_rgba_button_color + ';'"
|
||||
aria-expanded="true">
|
||||
<i class="fa fa-book"/>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right" style="width:20rem">
|
||||
<!--Dynamic Rendering-->
|
||||
<div class="ks_chart_export_menu">
|
||||
<div class="ks_chart_export_menu_header" style="margin-left:-10px">
|
||||
<span>Info</span>
|
||||
</div>
|
||||
<div class="ks_info" style="margin-left:10px">
|
||||
<span>Company: <t t-esc="ks_company"/></span>
|
||||
</div>
|
||||
<div class="ks_info" style="margin-left:10px">
|
||||
<t t-if="ks_info">
|
||||
<t t-foreach="ks_info" t-as="ks_description" t-key="ks_description_index">
|
||||
<span><t t-esc="ks_description"/></span>
|
||||
<br></br>
|
||||
</t>
|
||||
</t>
|
||||
<i class="fa fa-book"/>
|
||||
</button>
|
||||
<div role="menu" class="dropdown-menu dropdown-menu-right" style="width:20rem">
|
||||
<!--Dynamic Rendering-->
|
||||
<div class="ks_chart_export_menu">
|
||||
<div class="ks_chart_export_menu_header" style="margin-left:-10px">
|
||||
<span>Info</span>
|
||||
</div>
|
||||
<div class="ks_info" style="margin-left:10px">
|
||||
<span>Company:
|
||||
<t t-esc="ks_company"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="ks_info" style="margin-left:10px">
|
||||
<t t-if="ks_info">
|
||||
<t t-foreach="ks_info" t-as="ks_description" t-key="ks_description_index">
|
||||
<span>
|
||||
<t t-esc="ks_description"/>
|
||||
</span>
|
||||
<br></br>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<t t-if="ksIsDashboardManager">
|
||||
<div class="dropdown d-md-none dn-setting-panel">
|
||||
<button class="btn btn-secondary border-0" type="button" id="dropdownSettingButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" >
|
||||
<i class="fa fa-cog"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownSettingButton">
|
||||
<a class="dropdown-item ks_dashboard_item_customize" >
|
||||
<i class="fa fa-pencil"></i> Customize Item
|
||||
</a>
|
||||
|
||||
<a class="dropdown-item ks_dashboard_item_delete" >
|
||||
<i class="fa fa-times"></i> Remove Item
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary border-0" type="button" id="dropdownSettingButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" >
|
||||
<i class="fa fa-cog"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownSettingButton">
|
||||
<a class="dropdown-item ks_dashboard_item_customize" >
|
||||
<i class="fa fa-pencil"></i> Customize Item
|
||||
</a>
|
||||
<a class="dropdown-item ks_dashboard_item_delete" >
|
||||
<i class="fa fa-times"></i> Remove Item
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card-header">
|
||||
<div class="nav-tabs-navigation">
|
||||
<div class="nav-tabs-wrapper">
|
||||
@@ -172,7 +168,6 @@
|
||||
<t t-esc="table_header"/>
|
||||
</a>
|
||||
</t>
|
||||
|
||||
</li>
|
||||
<t t-set="ks_rec_count" t-value="ks_rec_count+1"/>
|
||||
</t>
|
||||
@@ -191,7 +186,6 @@
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -202,16 +196,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
<t t-name="ks_to_do_dashboard_inner_body">
|
||||
<div class="container-fluid p-0">
|
||||
<div>
|
||||
<div>
|
||||
|
||||
<div class="card">
|
||||
<t t-if="state.to_do_view_data['label']">
|
||||
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<t t-set="ks_section_count" t-value="0"/>
|
||||
@@ -232,7 +222,6 @@
|
||||
<td class="ks_custom_check">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
|
||||
<t t-if="state.to_do_view_data['ks_content_active'][ks_href_id][ks_temp_count]=='True'">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
@@ -243,7 +232,6 @@
|
||||
type="checkbox" value=""
|
||||
checked=""/>
|
||||
</t>
|
||||
|
||||
<span class="form-check-sign ks_do_item_active_handler" t-on-click="_onKsActiveHandler"
|
||||
t-att-data-item-id="item_id"
|
||||
t-att-data-content-id="state.to_do_view_data['ks_content_record_id'][ks_href_id][ks_temp_count]"
|
||||
@@ -262,7 +250,6 @@
|
||||
<t t-esc="table_row"/>
|
||||
</td>
|
||||
</t>
|
||||
|
||||
<t t-else="">
|
||||
<td class="ks_description ks_do_item_line_through"
|
||||
t-att-value="table_row"
|
||||
@@ -294,14 +281,12 @@
|
||||
<t t-set="ks_temp_count" t-value="ks_temp_count+1"/>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
</t>
|
||||
</table>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="nav-tabs-title">No Tasks Available</span>
|
||||
</t>
|
||||
|
||||
<t t-set="ks_section_count" t-value="ks_section_count+1"/>
|
||||
</div>
|
||||
</t>
|
||||
@@ -350,7 +335,6 @@
|
||||
<t t-esc="table_row"/>
|
||||
</td>
|
||||
</t>
|
||||
|
||||
<t t-else="">
|
||||
<td class="ks_description ks_do_item_line_through"
|
||||
t-att-value="table_row"
|
||||
@@ -382,7 +366,6 @@
|
||||
<t t-set="ks_temp_count" t-value="ks_temp_count+1"/>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
</t>
|
||||
</table>
|
||||
</t>
|
||||
@@ -404,10 +387,8 @@
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -59,7 +59,7 @@
|
||||
<xpath expr="////div[@class='o_control_panel d-flex flex-column gap-3 gap-lg-1 px-3 pt-2 pb-3']" position="after">
|
||||
<div class="o_control_panel th_custom_control_panel d-flex gap-1" t-if="env.isSmall">
|
||||
<div class="th_custom_control_panel_buttons">
|
||||
<!-- 用于放置按钮-->
|
||||
<!-- 用于放置按钮-->
|
||||
</div>
|
||||
|
||||
<!-- 返回箭头-->
|
||||
@@ -72,8 +72,9 @@
|
||||
<div t-if="collapsedBreadcrumbs.length || visiblePathBreadcrumbs.length" class="o_breadcrumb d-flex flex-row flex-md-column align-self-stretch justify-content-between min-w-0">
|
||||
<t t-if="env.isSmall">
|
||||
<t t-set="previousBreadcrumb" t-value="visiblePathBreadcrumbs.slice(-1)"/>
|
||||
<button class="o_back_button btn btn-link px-1" t-on-click.prevent="() => this.onBreadcrumbClicked(previousBreadcrumb.jsId)">
|
||||
<i class="oi oi-fw oi-arrow-left"/>
|
||||
<button class="o_back_button btn btn-primary px-1" t-on-click.prevent="() => this.onBreadcrumbClicked(previousBreadcrumb.jsId)">
|
||||
<!-- <i class="oi oi-fw oi-arrow-left"/>-->
|
||||
返回
|
||||
</button>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
@@ -209,6 +209,31 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
soong_record_ids = fields.One2many(comodel_name="soong.workflow.line", inverse_name="res_id", string=" ",)
|
||||
project_ids = fields.One2many(comodel_name="project.project.line", inverse_name="res_id", string=" ",)
|
||||
|
||||
def get_logs_for_print(self, applicant_first=False):
|
||||
"""
|
||||
返回用于打印的审批日志列表:
|
||||
- 按与界面相同的顺序(sequence 升序)
|
||||
- 同名节点只保留最新一条
|
||||
- 可选:申请人置顶
|
||||
"""
|
||||
self.ensure_one()
|
||||
logs = self.log_ids.sorted('sequence')
|
||||
seen = set()
|
||||
ordered = []
|
||||
# 逆序去重,保留最新
|
||||
for log in reversed(logs):
|
||||
key = log.name or ''
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
ordered.append(log)
|
||||
ordered.reverse() # 恢复原有顺序(去重后)
|
||||
if applicant_first:
|
||||
applicants = [l for l in ordered if (l.name or '') == '申请人']
|
||||
others = [l for l in ordered if (l.name or '') != '申请人']
|
||||
ordered = applicants + others
|
||||
return ordered
|
||||
|
||||
# @api.model_create_multi
|
||||
# def create(self, vals_list):
|
||||
# res = super().create(vals_list)
|
||||
|
||||
@@ -16,10 +16,7 @@ class SoongWorkflowRecord(models.Model):
|
||||
|
||||
def get_workflow_count(self):
|
||||
domain = [
|
||||
('soong_state', 'in', ['to_do', 'active']),
|
||||
('employee_ids.user_id', '=', self.env.user.id),
|
||||
('users_ids', 'in', self.env.user.id),
|
||||
('reclaim_state', '=', False)
|
||||
('is_to_do', '=', True),
|
||||
]
|
||||
return self.search_count(domain)
|
||||
|
||||
@@ -74,6 +71,41 @@ class SoongWorkflowRecord(models.Model):
|
||||
# 人力资源流程的发生日期
|
||||
workflow_happen_date = fields.Date(string="发生日期")
|
||||
is_unlink = fields.Boolean(string="是否可删", compute='_compute_is_unlink')
|
||||
is_to_do = fields.Boolean(
|
||||
string="是否是待办流程",
|
||||
compute='_compute_is_to_do',
|
||||
search='_search_is_to_do',
|
||||
)
|
||||
@api.depends('employee_ids', 'soong_state', 'reclaim_state')
|
||||
def _compute_is_to_do(self):
|
||||
current_uid = self.env.user.id
|
||||
for record in self:
|
||||
record.is_to_do = False
|
||||
condition1 = record.soong_state in ['to_do', 'to_active']
|
||||
condition2 = not record.reclaim_state
|
||||
condition3 = False
|
||||
if record.employee_ids:
|
||||
condition3 = current_uid in record.employee_ids.mapped('user_id.id')
|
||||
if condition1 and condition2 and condition3:
|
||||
record.is_to_do = True
|
||||
|
||||
def _search_is_to_do(self, operator, value):
|
||||
current_uid = self.env.user.id
|
||||
current_employee_ids = self.env['hr.employee'].search([
|
||||
('user_id', '=', current_uid)
|
||||
]).ids
|
||||
base_domain = [
|
||||
('soong_state', 'in', ['to_do', 'to_active']),
|
||||
('reclaim_state', '=', False),
|
||||
('employee_ids', 'in', current_employee_ids)
|
||||
]
|
||||
if (operator == '=' and value) or (operator == '!=' and not value):
|
||||
domain = base_domain
|
||||
elif (operator == '=' and not value) or (operator == '!=' and value):
|
||||
domain = ['!'] + base_domain
|
||||
else:
|
||||
domain = []
|
||||
return domain
|
||||
|
||||
@api.depends_context('uid', 'company')
|
||||
@api.depends('department_id', 'employee_ids')
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<notebook>
|
||||
<page string="审批详情">
|
||||
<field name="log_ids" style="width:100%; margin-top: 10px;" mode="kanban,tree" context="{'kanban_view_ref':'soong_workflow.soong_workflow_log_kanban'}">
|
||||
<tree editable="bottom">
|
||||
<tree editable="bottom" create="1" edit="1" delete="1">
|
||||
<field name="sequence" string="" widget="handle" groups="soong_workflow.group_soong_workflow_manager"/>
|
||||
<field name="name" string="" readonly="0"/>
|
||||
<field name="comment" string=""/>
|
||||
@@ -20,7 +20,7 @@
|
||||
</page>
|
||||
<page string="抄送/传阅记录" invisible="not log_ids2" mode="kanban,tree" context="{'kanban_view_ref':'soong_workflow.soong_workflow_log2_kanban'}">
|
||||
<field name="log_ids2" style="width:100%; margin-top: 10px;">
|
||||
<tree editable="bottom" >
|
||||
<tree editable="bottom" create="1" edit="1" delete="1">
|
||||
<field name="done_by" string=""/>
|
||||
<field name="commit" string=""/>
|
||||
<field name="lase_click_date" string=""/>
|
||||
@@ -32,7 +32,7 @@
|
||||
</page>
|
||||
<page string="关联流程">
|
||||
<field name="soong_record_ids" style="width:100%; margin-top: 10px;">
|
||||
<tree edit="true" delete="False" editable="bottom" type="object">
|
||||
<tree create="1" edit="1" delete="1" editable="bottom" type="object">
|
||||
<field name="workflow_record_id" domain="[('users_ids', 'in', uid)]"
|
||||
options="{'no_open': True}"/>
|
||||
<field name="code" column_invisible="1"/>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="流程查询" action="open_record" type="object"
|
||||
decoration-danger="approve_state == 'end'" delete="false"
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="15">
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="10">
|
||||
<header>
|
||||
<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"/>
|
||||
@@ -162,7 +162,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="流程查询" action="open_record" type="object"
|
||||
decoration-danger="approve_state == 'end'" delete="false"
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="15">
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="10">
|
||||
<header>
|
||||
<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"/>
|
||||
@@ -191,7 +191,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="流程查询" action="open_record" type="object"
|
||||
decoration-danger="approve_state == 'end'" delete="false"
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="15">
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="10">
|
||||
<field name="code"/>
|
||||
<field name="workflow_id" string="审批类型"/>
|
||||
<field name="name"/>
|
||||
@@ -211,7 +211,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="流程查询" action="open_record" type="object"
|
||||
decoration-danger="approve_state == 'end'" delete="false"
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="15">
|
||||
create="false" default_order="write_date2 desc, id desc" expand="1" limit="10">
|
||||
<header>
|
||||
<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"/>
|
||||
@@ -273,7 +273,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree string="工作流回收站" action="open_record" type="object"
|
||||
decoration-muted="approve_state == 'end'" decoration-warning="approve_state != 'end'"
|
||||
create="false" default_order="write_date2 desc" limit="15">
|
||||
create="false" default_order="write_date2 desc" limit="10">
|
||||
<field name="name"/>
|
||||
<field name="workflow_id" string="审批类型"/>
|
||||
<field name="node_id" string="当前节点"/>
|
||||
@@ -317,7 +317,7 @@
|
||||
<field name="res_model">soong.workflow.record</field>
|
||||
<field name="view_mode">tree,kanban,search</field>
|
||||
<field name="context">{'header_search_default_approve_state': 1, 'header_search_default_to_do':1, 'check_employee': 1}</field>
|
||||
<field name="domain">[('users_ids', 'in', uid), ('reclaim_state', '=', False), ('soong_state', 'in', ['to_do', 'to_active'])]</field>
|
||||
<field name="domain">[('is_to_do', '=', True)]</field>
|
||||
<field name="search_view_id" ref="soong_workflow_record_search1"/>
|
||||
<field name="view_id" ref="soong_workflow_record_my_tree"/>
|
||||
</record>
|
||||
|
||||
@@ -450,7 +450,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
for employee in self.employee_ids:
|
||||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||||
_logger.info(f"===================当前的url为{url}=============================")
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||||
user_id=employee.wecom_userid,
|
||||
@@ -695,7 +695,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
recipients = [emp for emp in employees]
|
||||
for employee in recipients:
|
||||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||||
if self.res_model == 'purchase.order':
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||||
user_id=employee.wecom_userid,
|
||||
@@ -716,7 +716,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
|
||||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={menu_id.id}&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
|
||||
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
|
||||
if self.employee_ids:
|
||||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.employee_ids if employee.user_id]
|
||||
@@ -731,6 +730,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
"done_by": self.employee_ids.user_id.id,
|
||||
"node_btn_name": "0",
|
||||
})
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, self.employee_ids.user_id.id)
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=self.employee_ids.wecom_userid, title=record_id._description, description=description, url=url, btntxt="查看详情")
|
||||
if result_data and 'msgid' in result_data[-1]:
|
||||
msg_id = result_data[-1]['msgid']
|
||||
@@ -747,6 +747,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
"done_by": emp.user_id.id,
|
||||
"node_btn_name": "4",
|
||||
})
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, emp.user_id.id)
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=emp.wecom_userid, title=record_id._description + "承办", description=description, url=url, btntxt="查看详情")
|
||||
if result_data and 'msgid' in result_data[-1]:
|
||||
msg_id = result_data[-1]['msgid']
|
||||
@@ -781,6 +782,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
"node_btn_id": self.node_btn_id.id,
|
||||
"approval_state": "0",
|
||||
})
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description + "传阅/抄送",description=description, url=url, btntxt="查看详情")
|
||||
if result_data and 'msgid' in result_data[-1]:
|
||||
msg_id = result_data[-1]['msgid']
|
||||
@@ -839,7 +841,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
menu_id = self.env['ir.ui.menu'].search([('name', '=', '行政收文')])
|
||||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={menu_id.id}&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, category='oa')
|
||||
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
|
||||
record = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||||
record.log_ids[-1].write({'is_active_operate': True,
|
||||
@@ -875,6 +876,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
"node_btn_id": self.node_btn_id.id,
|
||||
"approval_state": "0",
|
||||
})
|
||||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||||
user_id=employee.wecom_userid,
|
||||
title=record_id._description + "传阅/抄送",
|
||||
|
||||
@@ -553,6 +553,32 @@ class HolidaysRequestBatch(models.Model):
|
||||
'text': f"请假审批"
|
||||
})
|
||||
|
||||
overtime_records = self.env['vacation.over.line'].search([
|
||||
('employee_id', '=', self.users_id.employee_ids.id),
|
||||
('remaining_quantity', '>', 0),
|
||||
('is_void', '=', False),
|
||||
('text', '!=', '上月继承额度'),
|
||||
], order='start_time ASC')
|
||||
|
||||
remaining_deduct = hours
|
||||
for record in overtime_records:
|
||||
if remaining_deduct <= 0:
|
||||
break
|
||||
current_remaining = record.remaining_quantity
|
||||
deduct_amount = min(remaining_deduct, current_remaining)
|
||||
if remaining_deduct > current_remaining:
|
||||
carry_state = 'partial'
|
||||
else:
|
||||
carry_state = 'completed'
|
||||
|
||||
record.write({
|
||||
'carry_forward_date': fields.Date.to_string(period_start),
|
||||
'carry_forward_quantity': deduct_amount,
|
||||
'carry_forward_state': carry_state,
|
||||
})
|
||||
remaining_deduct -= deduct_amount
|
||||
|
||||
|
||||
def _create_annual_leave_line(self, period_start, leave_data, hours, period):
|
||||
"""更新年假记录,使用小时作为单位(增加重复校验,避免重复创建)"""
|
||||
report_month = date(period_start.year, period_start.month, 1)
|
||||
|
||||
@@ -131,7 +131,8 @@
|
||||
<tr>
|
||||
<td class="section-cell" colspan="4">审批详情</td>
|
||||
</tr>
|
||||
<t t-foreach="doc.log_ids.sorted('sequence')" t-as="log">
|
||||
<t t-set="logs_ordered" t-value="doc.get_logs_for_print()"/>
|
||||
<t t-foreach="logs_ordered" t-as="log">
|
||||
<tr>
|
||||
<!-- 节点名称:保留center -->
|
||||
<!-- 若节点名称带“(物管)”等后缀,这里只取左侧文字 -->
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
'views/hr_attendance_portal_templates.xml',
|
||||
'views/meal_approval.xml',
|
||||
'views/applet_address_views.xml',
|
||||
# 'views/yuthon_holiday_statement.xml',
|
||||
'views/yuthon_holiday_statement.xml',
|
||||
'views/all_attendance_menu.xml',
|
||||
'views/overtime_approval_inherit_header.xml',
|
||||
|
||||
|
||||
@@ -48,18 +48,6 @@ class OvertimeApprovals(models.Model):
|
||||
work_end = fields.Boolean(string="结束")
|
||||
is_over = fields.Boolean(string="超过", compute="_compute_duration")
|
||||
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
carry_forward_duration = fields.Float(string="结转时长")
|
||||
carry_forward_result = fields.Selection([('success', '成功'),('failed', '失败')], string='结转结果',)
|
||||
validity = fields.Char(string="有效期")
|
||||
carry_forward_state = fields.Selection([('pending', '待结转'),('completed', '已结转'), ('partial', '部分结转')
|
||||
],string='结转状态',
|
||||
default='pending',
|
||||
)
|
||||
remaining_quantity = fields.Float(string='剩余数')
|
||||
|
||||
|
||||
|
||||
def action_print_overtime(self):
|
||||
self.ensure_one()
|
||||
return self.env.ref('yuthon_hr_attendance.action_overtime_approval_print').report_action(self)
|
||||
|
||||
@@ -2,24 +2,45 @@ from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, time, timedelta
|
||||
from odoo.exceptions import UserError
|
||||
from datetime import date, timedelta
|
||||
|
||||
class HolidayStatement(models.Model):
|
||||
class YuthonOvertimeReport(models.Model):
|
||||
_name = 'yuthon.holiday.statement'
|
||||
|
||||
class InheritHrLeave(models.Model):
|
||||
_inherit = 'hr.leave'
|
||||
_description = '请假情况'
|
||||
|
||||
leave_approval_type = fields.Char(string="审批类型")
|
||||
gender = fields.Selection([('male', '男'),('female', '女'),], string='性别', required=True, default='male')
|
||||
leave_title = fields.Char(string="标题")
|
||||
leave_summary = fields.Char(string="摘要")
|
||||
caption = fields.Char(string="标题", compute="_compute_application_reason")
|
||||
employee_id = fields.Many2one('hr.employee', string="发起人")
|
||||
leave_start_date = fields.Char(string="开始时间")
|
||||
leave_end_date = fields.Char(string="结束时间")
|
||||
leave_duration = fields.Char(string="请假时长")
|
||||
leave_stats = fields.Char(string="请假统计")
|
||||
application_reason = fields.Char(string="申请原因")
|
||||
leave_start_time = fields.Datetime(string="发起时间")
|
||||
leave_end_time = fields.Datetime(string="最后操作时间")
|
||||
approval_state = fields.Selection([
|
||||
('approved', '通过'),
|
||||
('rejected', '未通过')
|
||||
], string='审批状态')
|
||||
leave_stats = fields.Char(string="请假统计", compute="_compute_leave_stats")
|
||||
application_reason = fields.Char(string="申请原因", compute="_compute_application_reason")
|
||||
|
||||
@api.depends('batch_id', 'hour_batch_id')
|
||||
def _compute_application_reason(self):
|
||||
for rec in self:
|
||||
if rec.batch_id:
|
||||
rec.application_reason = rec.batch_id.text
|
||||
rec.caption = rec.batch_id.name
|
||||
elif rec.hour_batch_id:
|
||||
rec.application_reason = rec.hour_batch_id.text
|
||||
rec.caption = rec.hour_batch_id.name
|
||||
else:
|
||||
rec.application_reason = ''
|
||||
rec.caption = ''
|
||||
|
||||
@api.depends('holiday_status_id', 'employee_id')
|
||||
def _compute_leave_stats(self):
|
||||
for record in self:
|
||||
record.leave_stats = ""
|
||||
current_year = datetime.now().year
|
||||
start_of_year = f"{current_year}-01-01"
|
||||
end_of_year = f"{current_year}-12-31"
|
||||
leave_records = self.env['hr.leave'].search([
|
||||
('employee_id', '=', record.employee_id.id),
|
||||
('holiday_status_id', '=', record.holiday_status_id.id),
|
||||
('date_from', '>=', start_of_year),
|
||||
('date_from', '<=', end_of_year),
|
||||
('state', '=', 'validate'),
|
||||
])
|
||||
total_days = sum(leave.number_of_days for leave in leave_records)
|
||||
leave_type_name = record.holiday_status_id.name
|
||||
record.leave_stats = f"本年内已请{leave_type_name}{total_days:.1f}天"
|
||||
@@ -1,34 +0,0 @@
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, time, timedelta
|
||||
from odoo.exceptions import UserError
|
||||
from datetime import date, timedelta
|
||||
|
||||
|
||||
class YuthonOvertimeReport(models.Model):
|
||||
_name = 'yuthon.overtime.report'
|
||||
_description = '加班情况'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string="员工")
|
||||
department_id = fields.Many2one('hr.department',string="部门")
|
||||
overtime_date = fields.Char(string="加班时间")
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
carry_forward_duration = fields.Float(string="结转时长")
|
||||
carry_forward_result = fields.Selection(
|
||||
selection=[
|
||||
('success', '成功'),
|
||||
('failed', '失败')
|
||||
],
|
||||
string='结转结果',
|
||||
)
|
||||
validity = fields.Char(string="有效期")
|
||||
carry_forward_state = fields.Selection(
|
||||
selection=[
|
||||
('pending', '待结转'),
|
||||
('completed', '已结转'),
|
||||
('partial', '部分结转')
|
||||
],
|
||||
string='结转状态',
|
||||
default='pending',
|
||||
)
|
||||
remaining_quantity = fields.Float(string='剩余数')
|
||||
|
||||
@@ -86,7 +86,6 @@ class YuthonVacationReports(models.Model):
|
||||
attendance_message_log_ids = fields.One2many('attendance.message.log', 'vacation_id')
|
||||
admin_confirms = fields.Boolean(string="是否管理员确认")
|
||||
|
||||
|
||||
vacation_state = fields.Selection(
|
||||
selection=[
|
||||
('not_sent', "未发送"),
|
||||
@@ -931,7 +930,8 @@ class VacationOverline(models.Model):
|
||||
_description = '加班明细'
|
||||
|
||||
vacation_id = fields.Many2one('yuthon.vacation.reports', string='关联假期额度记录')
|
||||
employee_id = fields.Many2one('hr.employee', string='员工')
|
||||
employee_id = fields.Many2one('hr.employee', string='员工', compute='_compute_employee_id', store=True)
|
||||
department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门")
|
||||
workflow_record_id = fields.Many2one('soong.workflow.record', string='流程')
|
||||
update_type= fields.Selection([('add', '增加'), ('reduce', '减少')], string='更新类型')
|
||||
workday = fields.Float(string='工作日')
|
||||
@@ -947,6 +947,57 @@ class VacationOverline(models.Model):
|
||||
text = fields.Text(string='备注')
|
||||
is_confirm = fields.Boolean(string="是否确认")
|
||||
|
||||
overtime_name = fields.Char(string="标题", compute="_compute_overtime", store=True)
|
||||
start_time = fields.Datetime(string="开始时间", compute="_compute_overtime", store=True)
|
||||
end_time = fields.Datetime(string="结束时间", compute="_compute_overtime", store=True)
|
||||
carry_forward_date = fields.Date(string="结转日期")
|
||||
duration = fields.Float(string="加班时长", compute="_compute_overtime", store=True)
|
||||
carry_forward_quantity = fields.Float(string="结转时长")
|
||||
validity = fields.Char(string="有效期")
|
||||
carry_forward_state = fields.Selection([('pending', '待结转'),('completed', '已结转'), ('partial', '部分结转')
|
||||
],string='结转状态',
|
||||
default='pending',
|
||||
)
|
||||
remaining_quantity = fields.Float(string='剩余数', compute="_compute_remaining_quantity", store=True)
|
||||
|
||||
def update_line(self):
|
||||
over_ids = self.env["vacation.over.line"].browse(
|
||||
self._context.get('active_ids', self._context.get('active_id')))
|
||||
for rec in over_ids:
|
||||
rec._compute_remaining_quantity()
|
||||
rec._compute_overtime()
|
||||
rec._compute_employee_id()
|
||||
|
||||
@api.depends('duration', 'carry_forward_quantity')
|
||||
def _compute_remaining_quantity(self):
|
||||
for rec in self:
|
||||
rec.remaining_quantity = rec.duration - rec.carry_forward_quantity
|
||||
|
||||
@api.depends('vacation_id')
|
||||
def _compute_employee_id(self):
|
||||
for rec in self:
|
||||
if rec.vacation_id:
|
||||
rec.employee_id = rec.vacation_id.employee_id.id
|
||||
elif not rec.employee_id:
|
||||
rec.employee_id = False
|
||||
|
||||
@api.depends('workflow_record_id')
|
||||
def _compute_overtime(self):
|
||||
for rec in self:
|
||||
if rec.workflow_record_id and rec.update_type == 'add':
|
||||
res_model = rec.workflow_record_id.res_model
|
||||
res_id = rec.workflow_record_id.res_id
|
||||
overtime_id = rec.env[res_model].search([('id', '=', res_id)])
|
||||
rec.overtime_name = overtime_id.name
|
||||
rec.start_time = overtime_id.start_time
|
||||
rec.end_time = overtime_id.end_time
|
||||
rec.duration = overtime_id.duration
|
||||
else:
|
||||
rec.overtime_name = ''
|
||||
rec.start_time = ''
|
||||
rec.end_time = ''
|
||||
rec.duration = 0
|
||||
|
||||
def action_void(self):
|
||||
self.is_void = True
|
||||
|
||||
@@ -969,6 +1020,8 @@ class VacationOverline(models.Model):
|
||||
|
||||
if vals.get('update_type') == 'reduce' and vals.get('vacation_id'):
|
||||
vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id'])
|
||||
current_vacation_date = vacation_main.vacation_date
|
||||
next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
|
||||
deduct_workday = vals.get('workday', 0.0)
|
||||
deduct_public = vals.get('public_holidays', 0.0)
|
||||
deduct_workday_convert = deduct_workday / 8
|
||||
@@ -983,8 +1036,6 @@ class VacationOverline(models.Model):
|
||||
is_cross_year = False
|
||||
# 计算下月1号并判断是否跨年
|
||||
if vacation_main.vacation_date:
|
||||
current_vacation_date = vacation_main.vacation_date
|
||||
next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
|
||||
is_cross_year = current_vacation_date.year != next_month_first_day.year
|
||||
|
||||
# 跨年场景
|
||||
@@ -1006,31 +1057,52 @@ class VacationOverline(models.Model):
|
||||
current_text = vals.get('text', '').strip()
|
||||
if current_text != '上月额度继承':
|
||||
vacation_main = self.env['yuthon.vacation.reports'].browse(vals['vacation_id'])
|
||||
current_vacation_date = vacation_main.vacation_date
|
||||
next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
|
||||
add_workday = vals.get('workday', 0.0)
|
||||
add_public = vals.get('public_holidays', 0.0)
|
||||
next_month_vacation = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', vacation_main.employee_id.id),
|
||||
('vacation_date', '=', next_month_first_day),
|
||||
('vacation_state', 'in', ['not_sent', 'pending']),
|
||||
], limit=1)
|
||||
if vacation_main:
|
||||
vacation_add_vals = {
|
||||
'year_workday': vacation_main.year_workday + add_workday / 8,
|
||||
'year_holiday': vacation_main.year_holiday + add_public / 8,
|
||||
}
|
||||
vacation_main.write(vacation_add_vals)
|
||||
next_month_vacation = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', vacation_main.employee_id.id),
|
||||
('vacation_date', '=', next_month_first_day),
|
||||
('vacation_state', 'in', ['not_sent', 'pending']),
|
||||
], limit=1)
|
||||
|
||||
if next_month_vacation:
|
||||
total_add_days = add_workday + add_public
|
||||
inherit_vacation = self.env['vacation.over.line'].search([
|
||||
('vacation_id', '=', next_month_vacation.id),
|
||||
('text', '=', '上月额度继承'),
|
||||
], limit=1)
|
||||
if inherit_vacation:
|
||||
inherit_vacation.write({
|
||||
'year_workday': next_month_vacation.year_workday + add_workday / 8,
|
||||
'year_holiday': next_month_vacation.year_holiday + add_public / 8,
|
||||
'workday': inherit_vacation.workday + total_add_days
|
||||
})
|
||||
|
||||
if vacation_main.vacation_date:
|
||||
current_vacation_date = vacation_main.vacation_date
|
||||
next_month_first_day = current_vacation_date + relativedelta(months=+1, day=1)
|
||||
# 必须是跨年才写入上年工作日
|
||||
is_cross_year = current_vacation_date.year != next_month_first_day.year
|
||||
next_month_vacation = self.env['yuthon.vacation.reports'].search([
|
||||
('employee_id', '=', vacation_main.employee_id.id),
|
||||
('vacation_date', '=', next_month_first_day),
|
||||
('vacation_state', 'in', ['not_sent', 'pending']),
|
||||
], limit=1)
|
||||
if is_cross_year:
|
||||
next_month_deduct_vals = {
|
||||
'last_workday': next_month_vacation.last_workday + add_workday / 8,
|
||||
'last_holiday': next_month_vacation.last_holiday + add_public / 8,
|
||||
}
|
||||
next_month_vacation.write(next_month_deduct_vals)
|
||||
next_month_vacation.previous_year = next_month_vacation.last_workday/8 + next_month_vacation.last_holiday / 8,
|
||||
|
||||
return super(VacationOverline, self).create(vals)
|
||||
|
||||
|
||||
@@ -67,7 +67,8 @@
|
||||
|
||||
<!-- 审批详情 -->
|
||||
<tr><td class="section" colspan="3">审批详情</td></tr>
|
||||
<t t-foreach="doc.log_ids.sorted('sequence')" t-as="log">
|
||||
<t t-set="logs_ordered" t-value="doc.get_logs_for_print()"/>
|
||||
<t t-foreach="logs_ordered" t-as="log">
|
||||
<tr>
|
||||
<td class="cell-content approval-name approval-col1" style="text-align:center;"><span t-esc="log.name"/></td>
|
||||
<td class="cell-content approval-col2 no-right-border approval-center"><span t-esc="log.comment"/></td>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
<field name="model">overtime.approval</field>
|
||||
<field name="arch" type="xml">
|
||||
<form create="0">
|
||||
|
||||
<!-- <header>-->
|
||||
<!-- <button name="put_hr_employee" type="object" string="Approve" class="oe_highlight"/>-->
|
||||
<!-- </header>-->
|
||||
@@ -127,29 +126,4 @@
|
||||
<field name="domain">[('users_id', '=', uid)]</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<record id="view_overtime_approval_report_tree" model="ir.ui.view">
|
||||
<field name="name">overtime.approval.tree</field>
|
||||
<field name="model">overtime.approval</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班情况" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="department_id"/>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="carry_forward_duration"/>
|
||||
<field name="carry_forward_result"/>
|
||||
<field name="carry_forward_state"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<field name="validity"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_overtime_approval_report" model="ir.actions.act_window">
|
||||
<field name="name">加班情况</field>
|
||||
<field name="res_model">overtime.approval</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="view_overtime_approval_report_tree"/>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,29 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_yuthon_holiday_statement_tree" model="ir.ui.view">
|
||||
<field name="name">yuthon.holiday.statement.tree</field>
|
||||
<field name="model">yuthon.holiday.statement</field>
|
||||
<record id="view_hr_leave_statement_tree" model="ir.ui.view">
|
||||
<field name="name">hr.leave.statement.tree</field>
|
||||
<field name="model">hr.leave</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="请假情况" editable="bottom">
|
||||
<tree string="请假情况" editable="bottom" limit="15">
|
||||
<field name="caption"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="leave_approval_type"/>
|
||||
<field name="gender"/>
|
||||
<field name="leave_title"/>
|
||||
<field name="leave_summary"/>
|
||||
<field name="leave_start_date"/>
|
||||
<field name="leave_end_date"/>
|
||||
<field name="leave_duration"/>
|
||||
<field name="leave_start_time"/>
|
||||
<field name="leave_end_time"/>
|
||||
<field name="employee_company_id"/>
|
||||
<field name="holiday_status_id"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="number_of_days" string="请假时长(天)"/>
|
||||
<field name="leave_stats"/>
|
||||
<field name="application_reason"/>
|
||||
<field name="approval_state"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_yuthon_holiday_statement_action" model="ir.actions.act_window">
|
||||
<field name="name">请假情况</field>
|
||||
<field name="res_model">yuthon.holiday.statement</field>
|
||||
<field name="res_model">hr.leave</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="view_hr_leave_statement_tree"/>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_yuthon_overtime_report_tree" model="ir.ui.view">
|
||||
<field name="name">yuthon.overtime.report.tree</field>
|
||||
<field name="model">yuthon.overtime.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班情况" editable="bottom">
|
||||
<field name="employee_id"/>
|
||||
<field name="department_id"/>
|
||||
<field name="overtime_date"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="carry_forward_duration"/>
|
||||
<field name="carry_forward_result"/>
|
||||
<field name="carry_forward_state"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<field name="validity"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_yuthon_overtime_report" model="ir.actions.act_window">
|
||||
<field name="name">加班情况</field>
|
||||
<field name="res_model">yuthon.overtime.report</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -5,8 +5,8 @@
|
||||
<field name="model">yuthon.vacation.reports</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="误餐情况">
|
||||
<field name="employee_id"/>
|
||||
<field name="meal_fee"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="meal_fee"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -286,7 +286,23 @@
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </page>-->
|
||||
<page string="汇总" invisible="1">
|
||||
<page string="管理员修改字段" groups="base.group_system">
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="previous_year"/>
|
||||
<field name="year_distribution"/>
|
||||
<field name="used_this_year"/>
|
||||
<field name="last_holiday"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="last_workday"/>
|
||||
<field name="year_holiday"/>
|
||||
<field name="year_workday"/>
|
||||
<field name="used_this_year1"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="汇总" >
|
||||
<group>
|
||||
<field name="is_late_card"/>
|
||||
<field name="is_early_card"/>
|
||||
@@ -491,10 +507,57 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_yuthon_vacation_overtime_tree" model="ir.ui.view">
|
||||
<field name="name">vacation.over.line.overtime.tree</field>
|
||||
<field name="model">vacation.over.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加班情况" editable="bottom">
|
||||
<field name="overtime_name"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="department_id"/>
|
||||
<field name="start_time"/>
|
||||
<field name="end_time"/>
|
||||
<field name="duration"/>
|
||||
<field name="carry_forward_quantity"/>
|
||||
<field name="carry_forward_date"/>
|
||||
<field name="carry_forward_state"/>
|
||||
<field name="remaining_quantity"/>
|
||||
<field name="validity"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_yuthon_vacation_overtime_search" model="ir.ui.view">
|
||||
<field name="name">vacation.over.line.overtime.search</field>
|
||||
<field name="model">vacation.over.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="加班情况">
|
||||
<field name="overtime_name"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="department_id"/>
|
||||
<field name="start_time"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_overtime_approval_report" model="ir.actions.act_window">
|
||||
<field name="name">加班情况</field>
|
||||
<field name="res_model">vacation.over.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('workflow_record_id','!=', False), ('update_type', '=', 'add')]</field>
|
||||
<field name="view_id" ref="view_yuthon_vacation_overtime_tree"/>
|
||||
<field name="search_view_id" ref="view_yuthon_vacation_overtime_search"/>
|
||||
</record>
|
||||
<record id="update_vacation_over_line" model="ir.actions.server">
|
||||
<field name="name">触发计算逻辑</field>
|
||||
<field name="model_id" ref="yuthon_hr_attendance.model_vacation_over_line"/>
|
||||
<field name="binding_model_id" ref="yuthon_hr_attendance.model_vacation_over_line"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.update_line()</field>
|
||||
</record>
|
||||
<record id="view_yuthon_vacation_meal_action" model="ir.actions.act_window">
|
||||
<field name="name">误餐情况</field>
|
||||
<field name="res_model">yuthon.vacation.reports</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('meal_fee', '!=', 0)]</field>
|
||||
<field name="context">{'search_default_group_by_employee_id': 1, 'search_default_group_by_vacation_month': True}</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_hr_attendance.view_yuthon_vacation_meal_tree')}),]"/>
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='department_id']" position="after">
|
||||
<field name="allowed_user_ids" invisible="1"/>
|
||||
<!-- <field name="allowed_user_ids" invisible="1"/>-->
|
||||
<field name="number"/>
|
||||
<field name="establishment_quotas"/>
|
||||
<field name="no_of_employee" string="在编人数"/>
|
||||
|
||||
@@ -92,7 +92,8 @@
|
||||
<tr>
|
||||
<td colspan="4" style="background-color: #d4e6f1; text-align: center;"><strong>审批详情</strong></td>
|
||||
</tr>
|
||||
<t t-foreach="doc.log_ids.sorted('sequence')" t-as="log">
|
||||
<t t-set="logs_ordered" t-value="doc.get_logs_for_print()"/>
|
||||
<t t-foreach="logs_ordered" t-as="log">
|
||||
<tr>
|
||||
<td colspan="1"><span t-esc="log.name"/></td>
|
||||
<!-- 核心修改:隐藏意见列右侧边框 -->
|
||||
|
||||
@@ -119,7 +119,8 @@
|
||||
<td class="header-cell" colspan="5" style="text-align:center;"><strong>审批详情</strong></td>
|
||||
</tr>
|
||||
<t t-if="doc.log_ids">
|
||||
<t t-foreach="doc.log_ids.sorted('sequence')" t-as="log">
|
||||
<t t-set="logs_ordered" t-value="doc.get_logs_for_print()"/>
|
||||
<t t-foreach="logs_ordered" t-as="log">
|
||||
<tr>
|
||||
<td class="approval-col1" style="text-align:center;"><span t-esc="log.name"/></td>
|
||||
<!-- 仅修改此处colspan为3,让approval-col2和approval-col3相邻 -->
|
||||
|
||||
@@ -116,7 +116,8 @@
|
||||
<div class="section">审批详情</div>
|
||||
<table class="po">
|
||||
<t t-if="doc.log_ids">
|
||||
<t t-foreach="doc.log_ids.sorted('sequence')" t-as="log">
|
||||
<t t-set="logs_ordered" t-value="doc.get_logs_for_print()"/>
|
||||
<t t-foreach="logs_ordered" t-as="log">
|
||||
<tr>
|
||||
<td class="text-center"><span t-esc="log.name or ''"/></td>
|
||||
<!-- 隐藏意见列右侧边框 + 内容居中 -->
|
||||
|
||||
@@ -42,18 +42,8 @@
|
||||
<tr t-if="doc.is_chapter == 'yes'"><td class="hdr"><strong>用章范围</strong></td><td colspan="2" class="cell-content"><t t-foreach="doc.scope_chapter_ids" t-as="scope"><span t-esc="scope.name"/><t t-if="not scope_last">、</t></t></td></tr>
|
||||
<tr><td class="hdr"><strong>附件清单</strong></td><td colspan="2" class="cell-content attachment-list"><t t-foreach="doc.document_ids" t-as="att"><div><t t-esc="att.name"/></div></t></td></tr>
|
||||
<tr><td class="section" colspan="3"><strong>审批详情</strong></td></tr>
|
||||
<!-- 按 sequence 逆序去重(同名节点保留最新) -->
|
||||
<t t-set="logs_sorted" t-value="doc.log_ids.sorted('sequence', reverse=True)"/>
|
||||
<t t-set="seen" t-value="set()"/>
|
||||
<t t-set="logs_dedup" t-value="[]"/>
|
||||
<t t-foreach="logs_sorted" t-as="log_tmp">
|
||||
<t t-if="(log_tmp.name or '') not in seen">
|
||||
<t t-set="seen" t-value="seen | {log_tmp.name or ''}"/>
|
||||
<t t-set="logs_dedup" t-value="logs_dedup + [log_tmp]"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-set="logs_final" t-value="logs_dedup"/>
|
||||
<t t-foreach="logs_final" t-as="log">
|
||||
<t t-set="logs_ordered" t-value="doc.get_logs_for_print(True)"/>
|
||||
<t t-foreach="logs_ordered" t-as="log">
|
||||
<tr>
|
||||
<td class="cell-content approval-name approval-col1"><span t-esc="log.name"/></td>
|
||||
<td class="cell-content approval-col2 no-right-border approval-center"><span t-esc="log.comment"/></td>
|
||||
|
||||
@@ -104,7 +104,8 @@
|
||||
<td class="header-cell" colspan="7" style="text-align:center; background-color: #d4e6f1;"><strong>审批详情</strong></td>
|
||||
</tr>
|
||||
<t t-if="doc.log_ids">
|
||||
<t t-foreach="doc.log_ids.sorted('sequence')" t-as="log">
|
||||
<t t-set="logs_ordered" t-value="doc.get_logs_for_print()"/>
|
||||
<t t-foreach="logs_ordered" t-as="log">
|
||||
<tr>
|
||||
<td class="approval-col1 approval-center" colspan="1" style="width:6em;"><span t-esc="log.name"/></td>
|
||||
<td class="approval-col2 no-right-border approval-center" colspan="4"><span t-esc="log.comment"/></td>
|
||||
|
||||
@@ -167,7 +167,8 @@ class YuthonWillTask(models.Model):
|
||||
if minute1 == now.minute and hour1 == now.hour:
|
||||
task.write({'task_state': 'done'})
|
||||
will_id = task.yuthon_will_task_id
|
||||
for employee_id in will_id.employee_ids:
|
||||
will_id.task_state = 'done'
|
||||
for employee_id in task.employee_ids:
|
||||
url = f'https://phone.thtzjt.com/phone/Schedule/{task.yuthon_will_task_id.id}/{employee_id.id}'
|
||||
data_date = '时间:' + (task.reminder_time + timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S") + '\n'
|
||||
data_name = "事项名称: " + task.yuthon_will_task_id.name + '\n'
|
||||
@@ -290,4 +291,5 @@ class YuthonWillTask(models.Model):
|
||||
'view_mode': 'tree',
|
||||
'res_model': 'yuthon.dates.task',
|
||||
'domain': [('yuthon_will_task_id', '=', self.id)],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,11 +170,11 @@
|
||||
parent="hr_attendance_root_board_menu"
|
||||
action="yuthon_hr_attendance.action_overtime_approval_report"
|
||||
sequence="15"/>
|
||||
<!-- <menuitem id="menu_yuthon_holiday_statement_board"-->
|
||||
<!-- name="请假情况"-->
|
||||
<!-- parent="hr_attendance_root_board_menu"-->
|
||||
<!-- action="yuthon_hr_attendance.view_yuthon_holiday_statement_action"-->
|
||||
<!-- sequence="16"/>-->
|
||||
<menuitem id="menu_yuthon_holiday_statement_board"
|
||||
name="请假情况"
|
||||
parent="hr_attendance_root_board_menu"
|
||||
action="yuthon_hr_attendance.view_yuthon_holiday_statement_action"
|
||||
sequence="16"/>
|
||||
<menuitem id="menu_yuthon_meal_case_board"
|
||||
name="误餐情况"
|
||||
parent="hr_attendance_root_board_menu"
|
||||
|
||||
Reference in New Issue
Block a user