|
@@ -278,6 +278,26 @@
|
|
|
>
|
|
>
|
|
|
<div class="bg-violet-light q-pb-md">
|
|
<div class="bg-violet-light q-pb-md">
|
|
|
<div class="row justify-end q-mb-sm q-gutter-sm">
|
|
<div class="row justify-end q-mb-sm q-gutter-sm">
|
|
|
|
|
+ <input
|
|
|
|
|
+ ref="importExamesInput"
|
|
|
|
|
+ type="file"
|
|
|
|
|
+ accept=".xlsx,.csv"
|
|
|
|
|
+ class="hidden"
|
|
|
|
|
+ @change="onExamesFileSelected"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
|
|
+ <q-btn
|
|
|
|
|
+ v-if="serviceTab.serviceType === 'exame'"
|
|
|
|
|
+ unelevated
|
|
|
|
|
+ icon="mdi-upload"
|
|
|
|
|
+ :label="$t('import_parceiro.import_exames')"
|
|
|
|
|
+ padding="6px 12px"
|
|
|
|
|
+ :disable="!partnerId"
|
|
|
|
|
+ :loading="importingExames"
|
|
|
|
|
+ class="btn-gradient"
|
|
|
|
|
+ @click="onImportExamesClick"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
<q-btn
|
|
<q-btn
|
|
|
unelevated
|
|
unelevated
|
|
|
icon="mdi-plus"
|
|
icon="mdi-plus"
|
|
@@ -342,7 +362,9 @@ import {
|
|
|
uploadMyPartnerMedia,
|
|
uploadMyPartnerMedia,
|
|
|
deleteMyPartnerMedia,
|
|
deleteMyPartnerMedia,
|
|
|
} from "src/api/partnerAgreement";
|
|
} from "src/api/partnerAgreement";
|
|
|
-import { getServicesByPartner } from "src/api/partnerAgreementService";
|
|
|
|
|
|
|
+import { permissionStore } from "src/stores/permission";
|
|
|
|
|
+import { getServicesByPartner, importServices } from "src/api/partnerAgreementService";
|
|
|
|
|
+import { useImportPoller } from "src/composables/useImportPoller";
|
|
|
import { formatToBRLCurrencyOrDash } from "src/helpers/utils";
|
|
import { formatToBRLCurrencyOrDash } from "src/helpers/utils";
|
|
|
import axios from "axios";
|
|
import axios from "axios";
|
|
|
|
|
|
|
@@ -361,6 +383,7 @@ const $q = useQuasar();
|
|
|
const { t } = useI18n();
|
|
const { t } = useI18n();
|
|
|
const { prepareFile } = useMediaFile();
|
|
const { prepareFile } = useMediaFile();
|
|
|
const { inputRules } = useInputRules();
|
|
const { inputRules } = useInputRules();
|
|
|
|
|
+const permission_store = permissionStore();
|
|
|
|
|
|
|
|
const loadingPage = ref(true);
|
|
const loadingPage = ref(true);
|
|
|
const partner = ref(null);
|
|
const partner = ref(null);
|
|
@@ -607,6 +630,87 @@ const loadServices = async () => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+const onImportExamesClick = () => {
|
|
|
|
|
+ if (!permission_store.getAccess("parceiro.servico", "add")) {
|
|
|
|
|
+ $q.notify({
|
|
|
|
|
+ type: "negative",
|
|
|
|
|
+ message: t("validation.permissions.add"),
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!partnerId.value) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const input = importExamesInput.value?.[0];
|
|
|
|
|
+
|
|
|
|
|
+ if (!input) {
|
|
|
|
|
+ console.error("Input de importação de exames não encontrado.");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ input.value = null;
|
|
|
|
|
+ input.click();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const onExamesFileSelected = async (event) => {
|
|
|
|
|
+ const file = event.target.files?.[0];
|
|
|
|
|
+
|
|
|
|
|
+ if (!file) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!partnerId.value) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const { import_id } = await importServices(
|
|
|
|
|
+ partnerId.value,
|
|
|
|
|
+ file,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ startExamesPolling(import_id, {
|
|
|
|
|
+ onComplete: async (stats) => {
|
|
|
|
|
+ $q.notify({
|
|
|
|
|
+ type: "positive",
|
|
|
|
|
+ message: t("import_parceiro.import_exames_result", {
|
|
|
|
|
+ created: stats?.created ?? 0,
|
|
|
|
|
+ updated: stats?.updated ?? 0,
|
|
|
|
|
+ }),
|
|
|
|
|
+ timeout: 7000,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ await loadServices();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onError: () => {
|
|
|
|
|
+ $q.notify({
|
|
|
|
|
+ type: "negative",
|
|
|
|
|
+ message: t("http.errors.failed"),
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onTimeout: () => {
|
|
|
|
|
+ $q.notify({
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ message: t("import_parceiro.import_exames_processing"),
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error(error);
|
|
|
|
|
+
|
|
|
|
|
+ $q.notify({
|
|
|
|
|
+ type: "negative",
|
|
|
|
|
+ message: t("http.errors.failed"),
|
|
|
|
|
+ });
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ event.target.value = null;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const onAddService = () => {
|
|
const onAddService = () => {
|
|
|
router.push({
|
|
router.push({
|
|
|
name: "ParceiroDadosServicoPage",
|
|
name: "ParceiroDadosServicoPage",
|
|
@@ -622,6 +726,13 @@ const onEditService = (svc) => {
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+//import de exames/serviços
|
|
|
|
|
+const importExamesInput = useTemplateRef("importExamesInput");
|
|
|
|
|
+const {
|
|
|
|
|
+ polling: importingExames,
|
|
|
|
|
+ start: startExamesPolling,
|
|
|
|
|
+} = useImportPoller();
|
|
|
|
|
+
|
|
|
// ─── Populate ────────────────────────────────────────────────────────────────
|
|
// ─── Populate ────────────────────────────────────────────────────────────────
|
|
|
const populateForms = (p) => {
|
|
const populateForms = (p) => {
|
|
|
if (!p) return;
|
|
if (!p) return;
|