Skip to content

Commit 73f0cb5

Browse files
author
Nethmin Dulsara
authored
OHRM5X-2222: Fix claim - related issues (orangehrm#1701)
* OHRM5X-2222: Fix date format not localized in "My Claim" list and "Employee Claim" list * OHRM5X-2217: Fix user can't edit the name of Event/Expense type even those Event/Expense Type not used for any claim request * OHRM5X-2181: Fix required validation on expense type drop-down fails during edit * OHRM5X-2223: Fix system displays a loader when adding an incorrect input in the employee name field on the assign claim screen * OHRM5X-2224: Fix "Invalid parameter" error displayed when attempting to edit an expense with a deleted expense name
1 parent 07a4dd3 commit 73f0cb5

File tree

15 files changed

+247
-34
lines changed

15 files changed

+247
-34
lines changed

src/client/src/orangehrmClaimPlugin/components/ClaimAttachment.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ import {convertFilesizeToString} from '@ohrm/core/util/helper/filesize';
7878
import AddAttachmentModal from './AddAttachmentModal.vue';
7979
import EditAttachmentModal from './EditAttachmentModal.vue';
8080
import useEmployeeNameTranslate from '@/core/util/composable/useEmployeeNameTranslate';
81+
import useLocale from '@/core/util/composable/useLocale';
82+
import {formatDate, parseDate} from '@ohrm/core/util/helper/datefns';
83+
import useDateFormat from '@/core/util/composable/useDateFormat';
8184
8285
export default {
8386
name: 'ClaimAttachment',
@@ -106,6 +109,8 @@ export default {
106109
},
107110
},
108111
setup(props) {
112+
const {locale} = useLocale();
113+
const {jsDateFormat} = useDateFormat();
109114
const http = new APIService(
110115
window.appGlobal.baseUrl,
111116
`/api/v2/claim/requests/${props.requestId}/attachments`,
@@ -116,7 +121,9 @@ export default {
116121
return data.map((item) => {
117122
return {
118123
id: item.id,
119-
attachedDate: item.date ? item.date : '',
124+
attachedDate: item.date
125+
? formatDate(parseDate(item.date), jsDateFormat, {locale})
126+
: '',
120127
filename: item.attachment.fileName ?? '',
121128
size: item.attachment.size
122129
? convertFilesizeToString(item.attachment.size, 2)

src/client/src/orangehrmClaimPlugin/components/ClaimExpenses.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ import DeleteConfirmationDialog from '@ohrm/components/dialogs/DeleteConfirmatio
8080
import {computed} from 'vue';
8181
import AddExpenseModal from './AddExpenseModal.vue';
8282
import EditExpenseModal from './EditExpenseModal.vue';
83+
import useLocale from '@/core/util/composable/useLocale';
84+
import {formatDate, parseDate} from '@ohrm/core/util/helper/datefns';
85+
import useDateFormat from '@/core/util/composable/useDateFormat';
8386
8487
export default {
8588
name: 'ClaimExpenses',
@@ -104,6 +107,8 @@ export default {
104107
},
105108
},
106109
setup(props) {
110+
const {locale} = useLocale();
111+
const {jsDateFormat} = useDateFormat();
107112
const http = new APIService(
108113
window.appGlobal.baseUrl,
109114
`/api/v2/claim/requests/${props.requestId}/expenses`,
@@ -113,7 +118,9 @@ export default {
113118
return data.map((item) => {
114119
return {
115120
id: item.id,
116-
date: item.date ? item.date : '',
121+
date: item.date
122+
? formatDate(parseDate(item.date), jsDateFormat, {locale})
123+
: '',
117124
amount: item.amount ? item.amount.toFixed(2) : '0.00',
118125
note: item.note ? item.note : '',
119126
expenseType: item.expenseType ? item.expenseType.name : '',

src/client/src/orangehrmClaimPlugin/pages/EditClaimEvent.vue

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
<oxd-input-field
3535
v-model="claimEvent.name"
3636
:label="$t('claim.event_name')"
37-
disabled
37+
:disabled="!canEdit"
38+
:rules="rules.name"
3839
required
3940
/>
4041
</oxd-form-row>
@@ -78,7 +79,10 @@
7879
import {OxdSwitchInput} from '@ohrm/oxd';
7980
import {navigate} from '@ohrm/core/util/helper/navigation';
8081
import {APIService} from '@/core/util/services/api.service';
81-
import {shouldNotExceedCharLength} from '@ohrm/core/util/validation/rules';
82+
import {
83+
required,
84+
shouldNotExceedCharLength,
85+
} from '@ohrm/core/util/validation/rules';
8286
8387
const initialClaimEvent = {
8488
name: '',
@@ -111,7 +115,10 @@ export default {
111115
return {
112116
isLoading: false,
113117
claimEvent: {...initialClaimEvent},
118+
canEdit: false,
119+
name: '',
114120
rules: {
121+
name: [required, shouldNotExceedCharLength(100)],
115122
description: [shouldNotExceedCharLength(1000)],
116123
},
117124
};
@@ -124,12 +131,32 @@ export default {
124131
.then((response) => {
125132
const {data} = response.data;
126133
this.claimEvent = {...data};
134+
this.name = data.name;
135+
this.canEdit = response.data.meta.canEdit;
136+
})
137+
.finally(() => {
138+
this.isLoading = false;
139+
});
140+
},
141+
created() {
142+
this.isLoading = true;
143+
this.http
144+
.getAll({limit: 0})
145+
.then((response) => {
146+
const {data} = response.data;
147+
this.rules.name.push((value) => {
148+
const index = data.findIndex(
149+
(item) =>
150+
value.trim().toLowerCase() !== this.name &&
151+
item.name.toLowerCase() == value.trim().toLowerCase(),
152+
);
153+
return index === -1 || this.$t('general.already_exists');
154+
});
127155
})
128156
.finally(() => {
129157
this.isLoading = false;
130158
});
131159
},
132-
133160
methods: {
134161
onCancel() {
135162
navigate('/claim/viewEvents');
@@ -138,6 +165,7 @@ export default {
138165
this.isLoading = true;
139166
this.http
140167
.update(this.id, {
168+
name: this.canEdit ? this.claimEvent.name : null,
141169
description: this.claimEvent.description,
142170
status: this.claimEvent.status,
143171
})

src/client/src/orangehrmClaimPlugin/pages/assignClaim/AssignClaimRequest.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
import {
9696
required,
9797
shouldNotExceedCharLength,
98+
validSelection,
9899
} from '@/core/util/validation/rules';
99100
import {APIService} from '@ohrm/core/util/services/api.service';
100101
import {navigate} from '@ohrm/core/util/helper/navigation';
@@ -141,7 +142,7 @@ export default {
141142
request: {...claimRequest},
142143
id: 0,
143144
rules: {
144-
employee: [required],
145+
employee: [required, validSelection],
145146
event: [required],
146147
currency: [required],
147148
remarks: [shouldNotExceedCharLength(1000)],

src/client/src/orangehrmClaimPlugin/pages/claimExpenseTypes/EditClaimExpenseType.vue

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
<oxd-input-field
3535
v-model="expenseTypes.name"
3636
:label="$t('general.name')"
37-
disabled
37+
:disabled="!canEdit"
38+
:rules="rules.name"
3839
required
3940
/>
4041
</oxd-form-row>
@@ -78,7 +79,10 @@
7879
import {OxdSwitchInput} from '@ohrm/oxd';
7980
import {navigate} from '@ohrm/core/util/helper/navigation';
8081
import {APIService} from '@/core/util/services/api.service';
81-
import {shouldNotExceedCharLength} from '@ohrm/core/util/validation/rules';
82+
import {
83+
required,
84+
shouldNotExceedCharLength,
85+
} from '@ohrm/core/util/validation/rules';
8286
8387
const initialExpenseTypes = {
8488
name: '',
@@ -111,7 +115,10 @@ export default {
111115
return {
112116
isLoading: false,
113117
expenseTypes: {...initialExpenseTypes},
118+
canEdit: false,
119+
name: '',
114120
rules: {
121+
name: [required, shouldNotExceedCharLength(100)],
115122
description: [shouldNotExceedCharLength(1000)],
116123
},
117124
};
@@ -124,6 +131,28 @@ export default {
124131
.then((response) => {
125132
const {data} = response.data;
126133
this.expenseTypes = {...data};
134+
this.name = data.name;
135+
this.canEdit = response.data.meta.canEdit;
136+
})
137+
.finally(() => {
138+
this.isLoading = false;
139+
});
140+
},
141+
142+
created() {
143+
this.isLoading = true;
144+
this.http
145+
.getAll({limit: 0})
146+
.then((response) => {
147+
const {data} = response.data;
148+
this.rules.name.push((value) => {
149+
const index = data.findIndex(
150+
(item) =>
151+
value.trim().toLowerCase() !== this.name &&
152+
item.name.toLowerCase() == value.trim().toLowerCase(),
153+
);
154+
return index === -1 || this.$t('general.already_exists');
155+
});
127156
})
128157
.finally(() => {
129158
this.isLoading = false;
@@ -138,6 +167,7 @@ export default {
138167
this.isLoading = true;
139168
this.http
140169
.update(this.id, {
170+
name: this.canEdit ? this.expenseTypes.name : null,
141171
description: this.expenseTypes.description,
142172
status: this.expenseTypes.status,
143173
})

src/client/src/orangehrmClaimPlugin/pages/employeeClaims/EmployeeClaims.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ import {validDateFormat} from '@/core/util/validation/rules';
134134
import useDateFormat from '@/core/util/composable/useDateFormat';
135135
import EmployeeAutocomplete from '@/core/components/inputs/EmployeeAutocomplete.vue';
136136
import useEmployeeNameTranslate from '@/core/util/composable/useEmployeeNameTranslate';
137-
137+
import useLocale from '@/core/util/composable/useLocale';
138+
import {formatDate, parseDate} from '@ohrm/core/util/helper/datefns';
138139
import {
139140
validSelection,
140141
endDateShouldBeAfterStartDate,
@@ -176,6 +177,8 @@ export default {
176177
const {sortDefinition, sortField, sortOrder, onSort} = useSort({
177178
sortDefinition: defaultSortOrder,
178179
});
180+
const {locale} = useLocale();
181+
const {jsDateFormat} = useDateFormat();
179182
180183
const serializedFilters = computed(() => {
181184
return {
@@ -211,7 +214,11 @@ export default {
211214
status:
212215
item.status.charAt(0).toUpperCase() +
213216
item.status.slice(1).toLowerCase(),
214-
submittedDate: item.submittedDate,
217+
submittedDate: formatDate(
218+
parseDate(item.submittedDate),
219+
jsDateFormat,
220+
{locale},
221+
),
215222
amount: Number(item.amount).toLocaleString('en-US', {
216223
minimumFractionDigits: 2,
217224
maximumFractionDigits: 2,

src/client/src/orangehrmClaimPlugin/pages/myClaims/MyClaims.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ import usePaginate from '@ohrm/core/util/composable/usePaginate';
120120
import ReferenceIdAutocomplete from '@/orangehrmClaimPlugin/components/ReferenceIdAutocomplete.vue';
121121
import ClaimEventDropdown from '@/orangehrmClaimPlugin/components/ClaimEventDropdown.vue';
122122
import StatusDropdown from '@/orangehrmClaimPlugin/components/StatusDropdown.vue';
123+
import useLocale from '@/core/util/composable/useLocale';
124+
import {formatDate, parseDate} from '@ohrm/core/util/helper/datefns';
123125
import {
124126
validDateFormat,
125127
endDateShouldBeAfterStartDate,
@@ -152,6 +154,8 @@ export default {
152154
const {sortDefinition, sortField, sortOrder, onSort} = useSort({
153155
sortDefinition: defaultSortOrder,
154156
});
157+
const {locale} = useLocale();
158+
const {jsDateFormat} = useDateFormat();
155159
156160
const serializedFilters = computed(() => {
157161
return {
@@ -185,7 +189,11 @@ export default {
185189
status:
186190
item.status.charAt(0).toUpperCase() +
187191
item.status.slice(1).toLowerCase(),
188-
submittedDate: item.submittedDate,
192+
submittedDate: formatDate(
193+
parseDate(item.submittedDate),
194+
jsDateFormat,
195+
{locale},
196+
),
189197
amount: Number(item.amount).toLocaleString('en-US', {
190198
minimumFractionDigits: 2,
191199
maximumFractionDigits: 2,

src/plugins/orangehrmClaimPlugin/Api/ClaimEventAPI.php

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use OrangeHRM\Core\Api\V2\EndpointCollectionResult;
3030
use OrangeHRM\Core\Api\V2\EndpointResourceResult;
3131
use OrangeHRM\Core\Api\V2\EndpointResult;
32+
use OrangeHRM\Core\Api\V2\Exception\InvalidParamException;
3233
use OrangeHRM\Core\Api\V2\Model\ArrayModel;
3334
use OrangeHRM\Core\Api\V2\ParameterBag;
3435
use OrangeHRM\Core\Api\V2\RequestParams;
@@ -50,9 +51,10 @@ class ClaimEventAPI extends Endpoint implements CrudEndpoint
5051
public const PARAMETER_NAME = 'name';
5152
public const PARAMETER_DESCRIPTION = 'description';
5253
public const PARAMETER_ID = 'id';
53-
public const PARAMETER_EVENTID = 'eventId';
54+
public const PARAMETER_EVENT_ID = 'eventId';
5455
public const PARAMETER_IDS = 'ids';
5556
public const PARAMETER_STATUS = 'status';
57+
public const PARAMETER_CAN_CLAIM_EVENT_EDIT = 'canEdit';
5658
public const DESCRIPTION_MAX_LENGTH = 1000;
5759
public const NAME_MAX_LENGTH = 100;
5860

@@ -168,7 +170,7 @@ public function getAll(): EndpointResult
168170
$this->getRequestParams()->getBooleanOrNull(RequestParams::PARAM_TYPE_QUERY, self::PARAMETER_STATUS)
169171
);
170172
$claimEventSearchFilterParams->setId(
171-
$this->getRequestParams()->getIntOrNull(RequestParams::PARAM_TYPE_QUERY, self::PARAMETER_EVENTID)
173+
$this->getRequestParams()->getIntOrNull(RequestParams::PARAM_TYPE_QUERY, self::PARAMETER_EVENT_ID)
172174
);
173175
$claimEvents = $this->getClaimService()->getClaimDao()->getClaimEventList($claimEventSearchFilterParams);
174176
$count = $this->getClaimService()->getClaimDao()->getClaimEventCount($claimEventSearchFilterParams);
@@ -197,7 +199,7 @@ public function getValidationRuleForGetAll(): ParamRuleCollection
197199
),
198200
$this->getValidationDecorator()->notRequiredParamRule(
199201
new ParamRule(
200-
self::PARAMETER_EVENTID,
202+
self::PARAMETER_EVENT_ID,
201203
new Rule(Rules::POSITIVE)
202204
)
203205
),
@@ -297,20 +299,29 @@ public function getValidationRuleForDelete(): ParamRuleCollection
297299
* property="data",
298300
* ref="#/components/schemas/Claim-ClaimEventModel"
299301
* ),
300-
* @OA\Property(property="meta", type="object")
302+
* @OA\Property(property="meta",
303+
* type="object",
304+
* @OA\Property(property="canEdit", type="boolean")
305+
* )
301306
* )
302307
* ),
303308
* @OA\Response(response="404", ref="#/components/responses/RecordNotFound")
304309
* )
305310
*
306311
* @inheritDoc
312+
* @throws InvalidParamException
307313
*/
308314
public function getOne(): EndpointResult
309315
{
310316
$id = $this->getRequestParams()->getInt(RequestParams::PARAM_TYPE_ATTRIBUTE, self::PARAMETER_ID);
311317
$claimEvent = $this->getClaimService()->getClaimDao()->getClaimEventById($id);
312318
$this->throwRecordNotFoundExceptionIfNotExist($claimEvent, ClaimEvent::class);
313-
return new EndpointResourceResult(ClaimEventModel::class, $claimEvent);
319+
$isUsed = $this->getClaimService()->getClaimDao()->isClaimEventUsed($id);
320+
return new EndpointResourceResult(
321+
ClaimEventModel::class,
322+
$claimEvent,
323+
new ParameterBag([self::PARAMETER_CAN_CLAIM_EVENT_EDIT => !$isUsed])
324+
);
314325
}
315326

316327
/**
@@ -337,6 +348,10 @@ public function getValidationRuleForGetOne(): ParamRuleCollection
337348
* @OA\RequestBody(
338349
* @OA\JsonContent(
339350
* @OA\Property(
351+
* property="name",
352+
* type="string"
353+
* ),
354+
* @OA\Property(
340355
* property="description",
341356
* type="string"
342357
* ),
@@ -360,12 +375,21 @@ public function getValidationRuleForGetOne(): ParamRuleCollection
360375
* @OA\Response(response="404", ref="#/components/responses/RecordNotFound")
361376
* )
362377
* @inheritDoc
378+
* @throws InvalidParamException
363379
*/
364380
public function update(): EndpointResult
365381
{
366382
$id = $this->getRequestParams()->getInt(RequestParams::PARAM_TYPE_ATTRIBUTE, self::PARAMETER_ID);
367383
$claimEvent = $this->getClaimService()->getClaimDao()->getClaimEventById($id);
368384
$this->throwRecordNotFoundExceptionIfNotExist($claimEvent, ClaimEvent::class);
385+
$canEditName = !$this->getClaimService()->getClaimDao()->isClaimEventUsed($id);
386+
$name = $this->getRequestParams()->getStringOrNull(RequestParams::PARAM_TYPE_BODY, self::PARAMETER_NAME);
387+
if (!$canEditName && $name !== null) {
388+
throw $this->getInvalidParamException(self::PARAMETER_NAME);
389+
}
390+
if ($canEditName && $name !== null) {
391+
$claimEvent->setName($name);
392+
}
369393
$this->setClaimEvent($claimEvent);
370394
return new EndpointResourceResult(ClaimEventModel::class, $claimEvent);
371395
}
@@ -391,7 +415,10 @@ public function getValidationRuleForUpdate(): ParamRuleCollection
391415
new ParamRule(
392416
self::PARAMETER_STATUS,
393417
new Rule(Rules::BOOL_VAL)
394-
)
418+
),
419+
$this->getValidationDecorator()->notRequiredParamRule(
420+
$this->getNameRule(true),
421+
),
395422
);
396423
}
397424
}

0 commit comments

Comments
 (0)