|
@@ -81,7 +81,7 @@
|
|
|
v-if="props.selectStudent"
|
|
v-if="props.selectStudent"
|
|
|
class="col-12"
|
|
class="col-12"
|
|
|
>
|
|
>
|
|
|
- <div class="row items-start no-wrap q-col-gutter-sm">
|
|
|
|
|
|
|
+ <div class="row items-start no-wrap q-col-gutter-sm" @keydown.enter.prevent>
|
|
|
<DefaultSelect
|
|
<DefaultSelect
|
|
|
v-model="selectedStudent"
|
|
v-model="selectedStudent"
|
|
|
v-model:error="validationErrors.student_id"
|
|
v-model:error="validationErrors.student_id"
|
|
@@ -151,7 +151,7 @@
|
|
|
v-model="form.protocol"
|
|
v-model="form.protocol"
|
|
|
v-model:error="validationErrors.protocol"
|
|
v-model:error="validationErrors.protocol"
|
|
|
label="Protocolo"
|
|
label="Protocolo"
|
|
|
- :rules="[optionalMaxLengthRule(255)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.max(255)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -160,7 +160,7 @@
|
|
|
v-model="form.signature_date"
|
|
v-model="form.signature_date"
|
|
|
v-model:error="validationErrors.signature_date"
|
|
v-model:error="validationErrors.signature_date"
|
|
|
label="Data Assinatura"
|
|
label="Data Assinatura"
|
|
|
- :rules="[optionalDateRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.date]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -169,7 +169,7 @@
|
|
|
v-model="form.end_date"
|
|
v-model="form.end_date"
|
|
|
v-model:error="validationErrors.end_date"
|
|
v-model:error="validationErrors.end_date"
|
|
|
label="Data Encerramento"
|
|
label="Data Encerramento"
|
|
|
- :rules="[optionalDateRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.date]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -183,6 +183,7 @@
|
|
|
option-label="name"
|
|
option-label="name"
|
|
|
option-value="id"
|
|
option-value="id"
|
|
|
:options="packages"
|
|
:options="packages"
|
|
|
|
|
+ :rules="[inputRules.required]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -193,7 +194,7 @@
|
|
|
disable
|
|
disable
|
|
|
label="Qtd. Aulas"
|
|
label="Qtd. Aulas"
|
|
|
type="number"
|
|
type="number"
|
|
|
- :rules="[optionalIntegerRangeRule(1)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.integerRange(1)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -207,7 +208,7 @@
|
|
|
option-label="label"
|
|
option-label="label"
|
|
|
option-value="value"
|
|
option-value="value"
|
|
|
:options="weekdays"
|
|
:options="weekdays"
|
|
|
- :rules="[optionalIntegerRangeRule(0, 6)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.integerRange(0, 6)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -217,7 +218,7 @@
|
|
|
v-model:error="validationErrors.start_time"
|
|
v-model:error="validationErrors.start_time"
|
|
|
label="Hora de Início"
|
|
label="Hora de Início"
|
|
|
mask="##:##"
|
|
mask="##:##"
|
|
|
- :rules="[optionalTimeRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.time]"
|
|
|
>
|
|
>
|
|
|
<template #append>
|
|
<template #append>
|
|
|
<q-icon name="mdi-clock-outline" />
|
|
<q-icon name="mdi-clock-outline" />
|
|
@@ -231,7 +232,7 @@
|
|
|
v-model:error="validationErrors.end_time"
|
|
v-model:error="validationErrors.end_time"
|
|
|
label="Hora de Término"
|
|
label="Hora de Término"
|
|
|
mask="##:##"
|
|
mask="##:##"
|
|
|
- :rules="[optionalTimeRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.time]"
|
|
|
>
|
|
>
|
|
|
<template #append>
|
|
<template #append>
|
|
|
<q-icon name="mdi-clock-outline" />
|
|
<q-icon name="mdi-clock-outline" />
|
|
@@ -249,7 +250,7 @@
|
|
|
option-label="label"
|
|
option-label="label"
|
|
|
option-value="value"
|
|
option-value="value"
|
|
|
:options="weekdays"
|
|
:options="weekdays"
|
|
|
- :rules="[optionalIntegerRangeRule(0, 6)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.integerRange(0, 6)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -259,7 +260,7 @@
|
|
|
v-model:error="validationErrors.second_start_time"
|
|
v-model:error="validationErrors.second_start_time"
|
|
|
label="Hora de Início"
|
|
label="Hora de Início"
|
|
|
mask="##:##"
|
|
mask="##:##"
|
|
|
- :rules="[optionalTimeRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.time]"
|
|
|
>
|
|
>
|
|
|
<template #append>
|
|
<template #append>
|
|
|
<q-icon name="mdi-clock-outline" />
|
|
<q-icon name="mdi-clock-outline" />
|
|
@@ -273,7 +274,7 @@
|
|
|
v-model:error="validationErrors.second_end_time"
|
|
v-model:error="validationErrors.second_end_time"
|
|
|
label="Hora de Término"
|
|
label="Hora de Término"
|
|
|
mask="##:##"
|
|
mask="##:##"
|
|
|
- :rules="[optionalTimeRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.time]"
|
|
|
>
|
|
>
|
|
|
<template #append>
|
|
<template #append>
|
|
|
<q-icon name="mdi-clock-outline" />
|
|
<q-icon name="mdi-clock-outline" />
|
|
@@ -293,7 +294,7 @@
|
|
|
v-model:error="validationErrors.due_day"
|
|
v-model:error="validationErrors.due_day"
|
|
|
label="Dia de Vencimento"
|
|
label="Dia de Vencimento"
|
|
|
type="number"
|
|
type="number"
|
|
|
- :rules="[optionalIntegerRangeRule(1, 31)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.integerRange(1, 31)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -322,7 +323,7 @@
|
|
|
option-label="label"
|
|
option-label="label"
|
|
|
option-value="value"
|
|
option-value="value"
|
|
|
:options="enrollmentInstallmentOptions"
|
|
:options="enrollmentInstallmentOptions"
|
|
|
- :rules="[optionalIntegerRangeRule(1, 12)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.integerRange(1, 12)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -340,7 +341,7 @@
|
|
|
v-model="form.enrollment_due_date"
|
|
v-model="form.enrollment_due_date"
|
|
|
v-model:error="validationErrors.enrollment_due_date"
|
|
v-model:error="validationErrors.enrollment_due_date"
|
|
|
label="Data Vencimento"
|
|
label="Data Vencimento"
|
|
|
- :rules="[optionalDateRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.date]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -369,7 +370,7 @@
|
|
|
option-label="label"
|
|
option-label="label"
|
|
|
option-value="value"
|
|
option-value="value"
|
|
|
:options="packageInstallmentOptions"
|
|
:options="packageInstallmentOptions"
|
|
|
- :rules="[optionalIntegerRangeRule(1, 13)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.integerRange(1, 13)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -387,7 +388,7 @@
|
|
|
v-model="form.package_due_date"
|
|
v-model="form.package_due_date"
|
|
|
v-model:error="validationErrors.package_due_date"
|
|
v-model:error="validationErrors.package_due_date"
|
|
|
label="Data 1ª Parcela"
|
|
label="Data 1ª Parcela"
|
|
|
- :rules="[optionalDateRule]"
|
|
|
|
|
|
|
+ :rules="[inputRules.date]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -399,7 +400,10 @@
|
|
|
v-model:error="validationErrors.early_payment_discount"
|
|
v-model:error="validationErrors.early_payment_discount"
|
|
|
label="Desconto até o vencimento (%)"
|
|
label="Desconto até o vencimento (%)"
|
|
|
type="number"
|
|
type="number"
|
|
|
- :rules="[optionalNumberRangeRule(0, 100)]"
|
|
|
|
|
|
|
+ :rules="[
|
|
|
|
|
+ inputRules.minValue(0),
|
|
|
|
|
+ inputRules.maxValue(100),
|
|
|
|
|
+ ]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -414,7 +418,7 @@
|
|
|
option-value="value"
|
|
option-value="value"
|
|
|
:options="paymentMethods"
|
|
:options="paymentMethods"
|
|
|
:rules="[
|
|
:rules="[
|
|
|
- optionalOneOfRule([
|
|
|
|
|
|
|
+ inputRules.oneOf([
|
|
|
'pix',
|
|
'pix',
|
|
|
'credit_card',
|
|
'credit_card',
|
|
|
'debit_card',
|
|
'debit_card',
|
|
@@ -429,7 +433,7 @@
|
|
|
v-model:error="validationErrors.interest_rate"
|
|
v-model:error="validationErrors.interest_rate"
|
|
|
label="Juros (%) a.m"
|
|
label="Juros (%) a.m"
|
|
|
type="number"
|
|
type="number"
|
|
|
- :rules="[optionalNumberRangeRule(0)]"
|
|
|
|
|
|
|
+ :rules="[inputRules.minValue(0)]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -439,7 +443,10 @@
|
|
|
v-model:error="validationErrors.fine_cancelled"
|
|
v-model:error="validationErrors.fine_cancelled"
|
|
|
label="Multa (%)"
|
|
label="Multa (%)"
|
|
|
type="number"
|
|
type="number"
|
|
|
- :rules="[optionalNumberRangeRule(0, 100)]"
|
|
|
|
|
|
|
+ :rules="[
|
|
|
|
|
+ inputRules.minValue(0),
|
|
|
|
|
+ inputRules.maxValue(100),
|
|
|
|
|
+ ]"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -514,7 +521,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { addYears, format, isValid, parse } from "date-fns";
|
|
|
|
|
|
|
+import { addYears, format } from "date-fns";
|
|
|
|
|
|
|
|
import {
|
|
import {
|
|
|
createStudentContract,
|
|
createStudentContract,
|
|
@@ -919,9 +926,6 @@ const calculateEndTime = (
|
|
|
).padStart(2, "0")}`;
|
|
).padStart(2, "0")}`;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const emptyOptionalValue = (value) =>
|
|
|
|
|
- value == null || value === "";
|
|
|
|
|
-
|
|
|
|
|
const fetchMedias = async () => {
|
|
const fetchMedias = async () => {
|
|
|
if (!props.contract) return;
|
|
if (!props.contract) return;
|
|
|
|
|
|
|
@@ -1075,85 +1079,6 @@ const openFile = (url) => {
|
|
|
window.open(url, "_blank");
|
|
window.open(url, "_blank");
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const optionalDateRule = (value) => {
|
|
|
|
|
- if (emptyOptionalValue(value)) return true;
|
|
|
|
|
-
|
|
|
|
|
- const parsedDate = parse(
|
|
|
|
|
- value,
|
|
|
|
|
- "dd/MM/yyyy",
|
|
|
|
|
- new Date(),
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- return (
|
|
|
|
|
- (isValid(parsedDate) &&
|
|
|
|
|
- format(parsedDate, "dd/MM/yyyy") === value) ||
|
|
|
|
|
- "Informe uma data válida."
|
|
|
|
|
- );
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-const optionalIntegerRangeRule =
|
|
|
|
|
- (min, max = null) =>
|
|
|
|
|
- (value) => {
|
|
|
|
|
- if (emptyOptionalValue(value)) return true;
|
|
|
|
|
-
|
|
|
|
|
- const number = Number(value);
|
|
|
|
|
-
|
|
|
|
|
- const withinRange =
|
|
|
|
|
- number >= min &&
|
|
|
|
|
- (max == null || number <= max);
|
|
|
|
|
-
|
|
|
|
|
- if (Number.isInteger(number) && withinRange) {
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return max == null
|
|
|
|
|
- ? `Informe um número inteiro maior ou igual a ${min}.`
|
|
|
|
|
- : `Informe um número inteiro entre ${min} e ${max}.`;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
-const optionalMaxLengthRule = (max) => (value) =>
|
|
|
|
|
- emptyOptionalValue(value) ||
|
|
|
|
|
- String(value).length <= max ||
|
|
|
|
|
- `Informe no máximo ${max} caracteres.`;
|
|
|
|
|
-
|
|
|
|
|
-const optionalNumberRangeRule =
|
|
|
|
|
- (min, max = null) =>
|
|
|
|
|
- (value) => {
|
|
|
|
|
- if (emptyOptionalValue(value)) return true;
|
|
|
|
|
-
|
|
|
|
|
- const number = Number(value);
|
|
|
|
|
-
|
|
|
|
|
- const withinRange =
|
|
|
|
|
- number >= min &&
|
|
|
|
|
- (max == null || number <= max);
|
|
|
|
|
-
|
|
|
|
|
- if (Number.isFinite(number) && withinRange) {
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return max == null
|
|
|
|
|
- ? `Informe um valor maior ou igual a ${min}.`
|
|
|
|
|
- : `Informe um valor entre ${min} e ${max}.`;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
-const optionalOneOfRule = (allowedValues) => (value) =>
|
|
|
|
|
- emptyOptionalValue(value) ||
|
|
|
|
|
- allowedValues.includes(value) ||
|
|
|
|
|
- "Selecione uma opção válida.";
|
|
|
|
|
-
|
|
|
|
|
-const optionalTimeRule = (value) => {
|
|
|
|
|
- if (emptyOptionalValue(value)) return true;
|
|
|
|
|
-
|
|
|
|
|
- const match = /^(\d{2}):(\d{2})$/.exec(value);
|
|
|
|
|
-
|
|
|
|
|
- return (
|
|
|
|
|
- (!!match &&
|
|
|
|
|
- Number(match[1]) <= 23 &&
|
|
|
|
|
- Number(match[2]) <= 59) ||
|
|
|
|
|
- "Informe um horário válido."
|
|
|
|
|
- );
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
const restoreDefaultContractDates = () => {
|
|
const restoreDefaultContractDates = () => {
|
|
|
restoringDefaultDates.value = true;
|
|
restoringDefaultDates.value = true;
|
|
|
|
|
|