5688-worker.calendar_workCenter #1580

Merged
vicent merged 11 commits from 5688-worker.calendar_workCenter into dev 2023-06-28 11:38:50 +00:00
6 changed files with 327 additions and 305 deletions
Showing only changes of commit b7b6f413ba - Show all commits

View File

@ -1,104 +1,112 @@
<vn-crud-model <div ng-if="$ctrl.worker.hasWorkCenter">
url="AbsenceTypes" <vn-crud-model
data="absenceTypes" url="AbsenceTypes"
auto-load="true"> data="absenceTypes"
</vn-crud-model> auto-load="true">
<div class="vn-w-lg"> </vn-crud-model>
<vn-card class="vn-pa-sm calendars"> <div class="vn-w-lg">
<vn-icon ng-if="::$ctrl.isSubordinate" icon="info" color-marginal <vn-card class="vn-pa-sm calendars">
vn-tooltip="To start adding absences, click an absence type from the right menu and then on the day you want to add an absence"> <vn-icon ng-if="::$ctrl.isSubordinate" icon="info" color-marginal
</vn-icon> vn-tooltip="To start adding absences, click an absence type from the right menu and then on the day you want to add an absence">
<vn-calendar </vn-icon>
ng-repeat="month in $ctrl.months" <vn-calendar
data="$ctrl.events" ng-repeat="month in $ctrl.months"
default-date="month" data="$ctrl.events"
format-day="$ctrl.formatDay($day, $element)" default-date="month"
display-controls="false" format-day="$ctrl.formatDay($day, $element)"
hide-contiguous="true" display-controls="false"
hide-year="true" hide-contiguous="true"
on-selection="$ctrl.onSelection($event, $days)"> hide-year="true"
</vn-calendar> on-selection="$ctrl.onSelection($event, $days)">
</vn-card> </vn-calendar>
</div> </vn-card>
<vn-side-menu side="right">
<div class="vn-pa-md">
<div class="totalBox vn-mb-sm" style="text-align: center;">
<h6>{{'Contract' | translate}} #{{$ctrl.businessId}}</h6>
<div>
{{'Used' | translate}} {{$ctrl.contractHolidays.holidaysEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.contractHolidays.totalHolidays || 0}} {{'days' | translate}}
</div>
<div>
{{'Spent' | translate}} {{$ctrl.contractHolidays.hoursEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.contractHolidays.totalHours || 0}} {{'hours' | translate}}
</div>
<div>
{{'Paid holidays' | translate}} {{$ctrl.contractHolidays.payedHolidays || 0}} {{'days' | translate}}
</div>
</div>
<div class="totalBox" style="text-align: center;">
<h6>{{'Year' | translate}} {{$ctrl.year}}</h6>
<div>
{{'Used' | translate}} {{$ctrl.yearHolidays.holidaysEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.yearHolidays.totalHolidays || 0}} {{'days' | translate}}
</div>
<div>
{{'Spent' | translate}} {{$ctrl.yearHolidays.hoursEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.yearHolidays.totalHours || 0}} {{'hours' | translate}}
</div>
</div>
<div class="vn-pt-md">
<vn-autocomplete label="Year"
data="$ctrl.yearFilter"
ng-model="$ctrl.year"
show-field="year"
value-field="year"
order="DESC">
</vn-autocomplete>
<vn-autocomplete label="Contract"
url="Workers/{{$ctrl.$params.id}}/contracts"
fields="['started', 'ended']"
ng-model="$ctrl.businessId"
search-function="{businessFk: $search}"
value-field="businessFk"
order="businessFk DESC"
limit="5">
<tpl-item>
<div>#{{businessFk}}</div>
<div class="text-caption text-secondary">
{{started | date: 'dd/MM/yyyy'}} - {{ended ? (ended | date: 'dd/MM/yyyy') : 'Indef.'}}
</div>
</tpl-item>
</vn-autocomplete>
</div>
<div name="absenceTypes" class="input vn-py-md" style="overflow: hidden;">
<vn-chip ng-repeat="absenceType in absenceTypes" ng-class="::{'selectable': $ctrl.isSubordinate}"
ng-click="$ctrl.pick(absenceType)">
<vn-avatar
ng-style="{backgroundColor: absenceType.rgb}">
<vn-icon icon="check" ng-if="absenceType.id == $ctrl.absenceType.id"></vn-icon>
</vn-avatar>
{{absenceType.name}}
</vn-chip>
</div>
<div class="vn-py-md">
<vn-chip>
<vn-avatar class="festive">
</vn-avatar>
<span translate>Festive</span>
</vn-chip>
<vn-chip>
<vn-avatar class="today">
</vn-avatar>
<span translate>Current day</span>
</vn-chip>
</div>
</div> </div>
</vn-side-menu> <vn-side-menu side="right">
<vn-confirm <div class="vn-pa-md">
vn-id="confirm" <div class="totalBox vn-mb-sm" style="text-align: center;">
message="This item will be deleted" <h6>{{'Contract' | translate}} #{{$ctrl.card.worker.hasWorkCenter}}</h6>
question="Are you sure you want to continue?"> <div>
</vn-confirm> {{'Used' | translate}} {{$ctrl.contractHolidays.holidaysEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.contractHolidays.totalHolidays || 0}} {{'days' | translate}}
</div>
<div>
{{'Spent' | translate}} {{$ctrl.contractHolidays.hoursEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.contractHolidays.totalHours || 0}} {{'hours' | translate}}
</div>
<div>
{{'Paid holidays' | translate}} {{$ctrl.contractHolidays.payedHolidays || 0}} {{'days' | translate}}
</div>
</div>
<div class="totalBox" style="text-align: center;">
<h6>{{'Year' | translate}} {{$ctrl.year}}</h6>
<div>
{{'Used' | translate}} {{$ctrl.yearHolidays.holidaysEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.yearHolidays.totalHolidays || 0}} {{'days' | translate}}
</div>
<div>
{{'Spent' | translate}} {{$ctrl.yearHolidays.hoursEnjoyed || 0}}
{{'of' | translate}} {{$ctrl.yearHolidays.totalHours || 0}} {{'hours' | translate}}
</div>
</div>
<div class="vn-pt-md">
<vn-autocomplete label="Year"
data="$ctrl.yearFilter"
ng-model="$ctrl.year"
show-field="year"
value-field="year"
order="DESC">
</vn-autocomplete>
<vn-autocomplete label="Contract"
url="Workers/{{$ctrl.$params.id}}/contracts"
fields="['started', 'ended']"
ng-model="$ctrl.businessId"
search-function="{businessFk: $search}"
value-field="businessFk"
order="businessFk DESC"
limit="5">
<tpl-item>
<div>#{{businessFk}}</div>
<div class="text-caption text-secondary">
{{started | date: 'dd/MM/yyyy'}} - {{ended ? (ended | date: 'dd/MM/yyyy') : 'Indef.'}}
</div>
</tpl-item>
</vn-autocomplete>
</div>
<div name="absenceTypes" class="input vn-py-md" style="overflow: hidden;">
<vn-chip ng-repeat="absenceType in absenceTypes" ng-class="::{'selectable': $ctrl.isSubordinate}"
ng-click="$ctrl.pick(absenceType)">
<vn-avatar
ng-style="{backgroundColor: absenceType.rgb}">
<vn-icon icon="check" ng-if="absenceType.id == $ctrl.absenceType.id"></vn-icon>
</vn-avatar>
{{absenceType.name}}
</vn-chip>
</div>
<div class="vn-py-md">
<vn-chip>
<vn-avatar class="festive">
</vn-avatar>
<span translate>Festive</span>
</vn-chip>
<vn-chip>
<vn-avatar class="today">
</vn-avatar>
<span translate>Current day</span>
</vn-chip>
</div>
</div>
</vn-side-menu>
<vn-confirm
vn-id="confirm"
message="This item will be deleted"
question="Are you sure you want to continue?">
</vn-confirm>
</div>
<div
ng-if="!$ctrl.worker.hasWorkCenter"
class="bg-title"
translate>
Autonomous worker
</div>

View File

@ -64,8 +64,7 @@ class Controller extends Section {
set worker(value) { set worker(value) {
this._worker = value; this._worker = value;
if (value && value.hasWorkCenter) {
if (value) {
this.getIsSubordinate(); this.getIsSubordinate();
this.getActiveContract(); this.getActiveContract();
} }

View File

@ -11,4 +11,5 @@ Choose an absence type from the right menu: Elige un tipo de ausencia desde el m
To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia
You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual
Current day: Día actual Current day: Día actual
Paid holidays: Vacaciones pagadas Paid holidays: Vacaciones pagadas
Autonomous worker: Trabajador autónomo

View File

@ -34,6 +34,8 @@ class Controller extends ModuleCard {
this.$http.get(`Workers/${this.$params.id}`, {filter}) this.$http.get(`Workers/${this.$params.id}`, {filter})
.then(res => this.worker = res.data); .then(res => this.worker = res.data);
this.$http.get(`Workers/${this.$params.id}/activeContract`)
.then(res => this.worker.hasWorkCenter = res.data.workCenterFk);
} }
} }

View File

@ -4,211 +4,219 @@
filter="::$ctrl.filter" filter="::$ctrl.filter"
data="$ctrl.hours"> data="$ctrl.hours">
</vn-crud-model> </vn-crud-model>
<vn-card class="vn-pa-lg vn-w-lg"> <div ng-if="$ctrl.card.worker.hasWorkCenter">
<vn-table model="model" auto-load="false"> <vn-card class="vn-pa-lg vn-w-lg">
<vn-thead> <vn-table model="model" auto-load="false">
<vn-tr> <vn-thead>
<vn-td ng-repeat="weekday in $ctrl.weekDays" center> <vn-tr>
<div class="weekday" translate>{{::$ctrl.weekdayNames[$index].name}}</div> <vn-td ng-repeat="weekday in $ctrl.weekDays" center>
<div> <div class="weekday" translate>{{::$ctrl.weekdayNames[$index].name}}</div>
<span>{{::weekday.dated | date: 'dd'}}</span>
<span title="{{::weekday.dated | date: 'MMMM' | translate}}" translate>
{{::weekday.dated | date: 'MMMM'}}
</span>
</div>
<vn-chip
title="{{::weekday.event.name}}"
ng-class="{invisible: !weekday.event}">
<vn-avatar
ng-style="::{backgroundColor: weekday.event.color}">
</vn-avatar>
<div> <div>
{{::weekday.event.name}} <span>{{::weekday.dated | date: 'dd'}}</span>
<span title="{{::weekday.dated | date: 'MMMM' | translate}}" translate>
{{::weekday.dated | date: 'MMMM'}}
</span>
</div> </div>
</vn-chip>
</vn-td>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr>
<vn-td ng-repeat="weekday in $ctrl.weekDays" class="hours vn-pa-none" expand>
<section ng-repeat="hour in weekday.hours">
<vn-icon
icon="{{
::hour.direction == 'in' ? 'arrow_forward' : 'arrow_back'
}}"
title="{{
::(hour.direction == 'in' ? 'In' : 'Out') | translate
}}"
ng-class="::{'invisible': hour.direction == 'middle'}">
</vn-icon>
<vn-chip <vn-chip
ng-class="::{'colored': hour.manual, 'clickable': true}" title="{{::weekday.event.name}}"
removable="::hour.manual" ng-class="{invisible: !weekday.event}">
on-remove="$ctrl.showDeleteDialog($event, hour)" <vn-avatar
ng-click="$ctrl.edit($event, hour)" ng-style="::{backgroundColor: weekday.event.color}">
> </vn-avatar>
<prepend> <div>
<vn-icon icon="edit" {{::weekday.event.name}}
vn-tooltip="Edit"> </div>
</vn-icon>
</prepend>
{{::hour.timed | date: 'HH:mm'}}
</vn-chip> </vn-chip>
</section> </vn-td>
</vn-td> </vn-tr>
</vn-tr> </vn-thead>
</vn-tbody> <vn-tbody>
<vn-tfoot> <vn-tr>
<vn-tr> <vn-td ng-repeat="weekday in $ctrl.weekDays" class="hours vn-pa-none" expand>
<vn-td ng-repeat="weekday in $ctrl.weekDays" center> <section ng-repeat="hour in weekday.hours">
{{$ctrl.formatHours(weekday.workedHours)}} h. <vn-icon
</vn-td> icon="{{
</vn-tr> ::hour.direction == 'in' ? 'arrow_forward' : 'arrow_back'
<vn-tr> }}"
<vn-td center ng-repeat="weekday in $ctrl.weekDays"> title="{{
<vn-icon-button ::(hour.direction == 'in' ? 'In' : 'Out') | translate
icon="add_circle" }}"
vn-tooltip="Add time" ng-class="::{'invisible': hour.direction == 'middle'}">
ng-click="$ctrl.showAddTimeDialog(weekday)"> </vn-icon>
</vn-icon-button> <vn-chip
</vn-td> ng-class="::{'colored': hour.manual, 'clickable': true}"
</vn-tr> removable="::hour.manual"
</vn-tfoot> on-remove="$ctrl.showDeleteDialog($event, hour)"
</vn-table> ng-click="$ctrl.edit($event, hour)"
</vn-card> >
<prepend>
<vn-icon icon="edit"
vn-tooltip="Edit">
</vn-icon>
</prepend>
{{::hour.timed | date: 'HH:mm'}}
</vn-chip>
</section>
</vn-td>
</vn-tr>
</vn-tbody>
<vn-tfoot>
<vn-tr>
<vn-td ng-repeat="weekday in $ctrl.weekDays" center>
{{$ctrl.formatHours(weekday.workedHours)}} h.
</vn-td>
</vn-tr>
<vn-tr>
<vn-td center ng-repeat="weekday in $ctrl.weekDays">
<vn-icon-button
icon="add_circle"
vn-tooltip="Add time"
ng-click="$ctrl.showAddTimeDialog(weekday)">
</vn-icon-button>
</vn-td>
</vn-tr>
</vn-tfoot>
</vn-table>
</vn-card>
<vn-button-bar ng-show="$ctrl.state" class="vn-w-lg"> <vn-button-bar ng-show="$ctrl.state" class="vn-w-lg">
<vn-button <vn-button
label="Satisfied" label="Satisfied"
disabled="$ctrl.state == 'CONFIRMED'" disabled="$ctrl.state == 'CONFIRMED'"
ng-if="$ctrl.isHimSelf" ng-if="$ctrl.isHimSelf"
ng-click="$ctrl.isSatisfied()"> ng-click="$ctrl.isSatisfied()">
</vn-button> </vn-button>
<vn-button <vn-button
label="Not satisfied" label="Not satisfied"
disabled="$ctrl.state == 'REVISE'" disabled="$ctrl.state == 'REVISE'"
ng-if="$ctrl.isHimSelf" ng-if="$ctrl.isHimSelf"
ng-click="reason.show()"> ng-click="reason.show()">
</vn-button> </vn-button>
<vn-button <vn-button
label="Reason" label="Reason"
ng-if="$ctrl.reason && ($ctrl.isHimSelf || $ctrl.isHr)" ng-if="$ctrl.reason && ($ctrl.isHimSelf || $ctrl.isHr)"
ng-click="reason.show()"> ng-click="reason.show()">
</vn-button> </vn-button>
<vn-button <vn-button
label="Resend" label="Resend"
ng-click="sendEmailConfirmation.show()" ng-click="sendEmailConfirmation.show()"
class="right" class="right"
vn-tooltip="Resend email of this week to the user" vn-tooltip="Resend email of this week to the user"
ng-show="::$ctrl.isHr"> ng-show="::$ctrl.isHr">
</vn-button> </vn-button>
</vn-button-bar> </vn-button-bar>
<vn-side-menu side="right"> <vn-side-menu side="right">
<div class="vn-pa-md"> <div class="vn-pa-md">
<div class="totalBox" style="text-align: center;"> <div class="totalBox" style="text-align: center;">
<h6 translate>Hours</h6> <h6 translate>Hours</h6>
<vn-label-value <vn-label-value
label="Week total" label="Week total"
value="{{$ctrl.weekTotalHours}} h."> value="{{$ctrl.weekTotalHours}} h.">
</vn-label-value> </vn-label-value>
<vn-label-value <vn-label-value
label="Finish at" label="Finish at"
value="{{$ctrl.getFinishTime()}}"> value="{{$ctrl.getFinishTime()}}">
</vn-label-value> </vn-label-value>
</div>
<vn-calendar
vn-id="calendar"
class="vn-pt-md"
ng-model="$ctrl.date"
format-week="$ctrl.formatWeek($element)"
on-move="$ctrl.getMailStates($date)"
has-events="$ctrl.hasEvents($day)">
</vn-calendar>
</div> </div>
<vn-calendar </vn-side-menu>
vn-id="calendar" <vn-dialog
class="vn-pt-md" vn-id="addTimeDialog"
ng-model="$ctrl.date" on-accept="$ctrl.addTime()"
format-week="$ctrl.formatWeek($element)" message="Add time">
on-move="$ctrl.getMailStates($date)" <tpl-body>
has-events="$ctrl.hasEvents($day)"> <vn-input-time
</vn-calendar> vn-one
</div> vn-focus
</vn-side-menu> ng-model="$ctrl.newTimeEntry.timed"
<vn-dialog label="Hour"
vn-id="addTimeDialog"
on-accept="$ctrl.addTime()"
message="Add time">
<tpl-body>
<vn-input-time
vn-one
vn-focus
ng-model="$ctrl.newTimeEntry.timed"
label="Hour"
required="true">
</vn-input-time>
<vn-autocomplete
label="Type"
ng-model="$ctrl.newTimeEntry.direction"
data="$ctrl.entryDirections"
select-fields="['code','description']"
show-field="description"
value-field="code"
required="true">
</vn-autocomplete>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>
<vn-confirm
vn-id="delete-entry-dialog"
on-accept="$ctrl.deleteTimeEntry()"
message="This time entry will be deleted"
question="Are you sure you want to delete this entry?">
</vn-confirm>
<!-- Edit entry Popover -->
<vn-popover vn-id="editEntry">
<vn-horizontal class="vn-pa-sm edit-time-entry">
<vn-autocomplete class="dense"
ng-model="$ctrl.selectedRow.direction"
data="$ctrl.entryDirections"
select-fields="['code','description']"
show-field="description"
value-field="code">
</vn-autocomplete>
<vn-icon-button vn-none
icon="check"
vn-tooltip="Save"
ng-click="$ctrl.save()">
</vn-icon-button>
</vn-horizontal>
</vn-popover>
<vn-dialog
vn-id="reason"
on-accept="$ctrl.isUnsatisfied()">
<tpl-body>
<div class="reasonDialog">
<vn-textarea
label="Reason"
ng-model="$ctrl.reason"
disabled="!$ctrl.isHimSelf"
rows="5"
required="true"> required="true">
</vn-textarea> </vn-input-time>
</div> <vn-autocomplete
</tpl-body> label="Type"
<tpl-buttons ng-if="$ctrl.isHimSelf"> ng-model="$ctrl.newTimeEntry.direction"
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/> data="$ctrl.entryDirections"
<button response="accept" translate>Save</button> select-fields="['code','description']"
</tpl-buttons> show-field="description"
</vn-dialog> value-field="code"
required="true">
</vn-autocomplete>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>
<vn-confirm
vn-id="delete-entry-dialog"
on-accept="$ctrl.deleteTimeEntry()"
message="This time entry will be deleted"
question="Are you sure you want to delete this entry?">
</vn-confirm>
<vn-dialog <!-- Edit entry Popover -->
vn-id="sendEmailConfirmation" <vn-popover vn-id="editEntry">
on-accept="$ctrl.resendEmail()" <vn-horizontal class="vn-pa-sm edit-time-entry">
message="Send time control email"> <vn-autocomplete class="dense"
<tpl-body> ng-model="$ctrl.selectedRow.direction"
<span translate>Are you sure you want to send it?</span> data="$ctrl.entryDirections"
</tpl-body> select-fields="['code','description']"
<tpl-buttons> show-field="description"
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/> value-field="code">
<button response="accept" translate>Confirm</button> </vn-autocomplete>
</tpl-buttons> <vn-icon-button vn-none
</vn-dialog> icon="check"
vn-tooltip="Save"
ng-click="$ctrl.save()">
</vn-icon-button>
</vn-horizontal>
</vn-popover>
<vn-dialog
vn-id="reason"
on-accept="$ctrl.isUnsatisfied()">
<tpl-body>
<div class="reasonDialog">
<vn-textarea
label="Reason"
ng-model="$ctrl.reason"
disabled="!$ctrl.isHimSelf"
rows="5"
required="true">
</vn-textarea>
</div>
</tpl-body>
<tpl-buttons ng-if="$ctrl.isHimSelf">
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>
<vn-dialog
vn-id="sendEmailConfirmation"
on-accept="$ctrl.resendEmail()"
message="Send time control email">
<tpl-body>
<span translate>Are you sure you want to send it?</span>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Confirm</button>
</tpl-buttons>
</vn-dialog>
</div>
<div
ng-if="!$ctrl.worker.hasWorkCenter"
class="bg-title"
translate>
Autonomous worker
</div>

View File

@ -151,6 +151,7 @@ class Controller extends Section {
} }
getAbsences() { getAbsences() {
if (!this.card.worker.hasWorkerCenter) return;
const fullYear = this.started.getFullYear(); const fullYear = this.started.getFullYear();
let params = { let params = {
workerFk: this.$params.id, workerFk: this.$params.id,
@ -485,5 +486,8 @@ ngModule.vnComponent('vnWorkerTimeControl', {
controller: Controller, controller: Controller,
bindings: { bindings: {
worker: '<' worker: '<'
},
require: {
card: '^vnWorkerCard'
} }
}); });