Compare commits

...
Author SHA1 Message Date
Jeppe Bundgaard 7180bbd6d4 Add limited backoffice role template actions 2026-07-07 03:23:32 +02:00
Jeppe BandJeppe Bundgaard 96ccc01d08 Add limited backoffice employee migration (#164)
Co-authored-by: Jeppe Bundgaard <jb@truckwash.dk>
2026-07-07 00:14:05 +02:00
Jeppe Bundgaard 2108dd6c94 Send Selvvask import period dates
Include selected invoice-period dates when importing XLVask usage from the Selvvask period view.
2026-07-06 23:49:36 +02:00
Jeppe BandJeppe Bundgaard ca2003f2d6 Allow hosted runners for manual frontend tests (#161)
* Allow hosted runners for manual frontend tests

* Fix hosted full E2E i18n failures

* Stabilize release assignment E2E selection

* Gate full E2E on focused regressions

---------

Co-authored-by: Jeppe Bundgaard <jb@truckwash.dk>
2026-07-06 22:38:29 +02:00
37 changed files with 2401 additions and 139 deletions
@@ -112,13 +112,24 @@ if (router.currentRoute.value.params.departmentId) {
}
const isImportLoading = ref(false);
const buildImportUsageParams = () => {
if (!props.inheritPeriodFilters) {
return {};
}
return {
...(props.initialDateFrom ? { dateFrom: props.initialDateFrom } : {}),
...(props.initialDateTo ? { dateTo: props.initialDateTo } : {}),
};
};
const importUsageButton = async () => {
isImportLoading.value = true;
try {
await SessionUser.request(
'/modules/xlvask/tasks/import-usage',
'GET',
{},
buildImportUsageParams(),
function (error) {
// This function is called when the request fails
console.error("Failed to import orders.", error);
@@ -62,7 +62,7 @@ if (props.autoLoad) {
</div>
</div>
</template>
<UsersTable :objects="list" />
<UsersTable :objects="list" @migrated="loadList" />
</TableLabeledPagination>
</template>
@@ -1,21 +1,136 @@
<script setup>
import EditableTableColumn from "@/components/displays/buttons/EditableTableColumn.vue";
import { useI18n } from 'vue-i18n';
import Swal from "sweetalert2";
const { t } = useI18n();
defineProps(['objects']);
import { ref } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { usePaginatedListInstance } from "@/components/pagination/paginatedList.vue";
const { loadList } = usePaginatedListInstance();
import { SessionUser } from "@/components/session/token/SessionUser.vue";
import ActionSettingsWheelButton from "@/components/displays/buttons/ActionSettingsWheelButton.vue";
import ActionSettingsWheelItem from "@/components/displays/buttons/ActionSettingsWheelItem.vue";
import ActionSettingsWheelItemLabel from "@/components/displays/buttons/ActionSettingsWheelItemLabel.vue";
const redirect = (path) => {
window.location = path;
}
const limitedBackofficeTemplates = ref([]);
const templatesLoading = ref(false);
const templatesLoadError = ref(false);
const applyingTemplateKey = ref("");
const canApplyLimitedBackofficeTemplates = computed(() => SessionUser.hasPermission("add_role_permission"));
const loadLimitedBackofficeTemplates = async () => {
if (!canApplyLimitedBackofficeTemplates.value || templatesLoading.value) {
return;
}
templatesLoading.value = true;
templatesLoadError.value = false;
try {
const templates = await SessionUser.objects.roles.functions.getLimitedBackofficePermissionTemplates();
limitedBackofficeTemplates.value = Array.isArray(templates) ? templates : [];
} catch (error) {
console.error("Failed to load limited backoffice permission templates", error);
templatesLoadError.value = true;
} finally {
templatesLoading.value = false;
}
};
const templateTranslation = (template, field) => {
const key = `templates.limited_backoffice.roles.${template?.key}.${field}`;
const translated = t(key);
return translated === key ? template?.[field] || template?.key || "" : translated;
};
const templateLabel = (template) => templateTranslation(template, "label");
const rolePermissions = (role) => (Array.isArray(role?.permissions) ? role.permissions : []);
const templatePermissions = (template) => (Array.isArray(template?.permissions) ? template.permissions : []);
const missingTemplatePermissions = (role, template) => {
const currentPermissions = new Set(rolePermissions(role));
return templatePermissions(template).filter((permission) => permission && !currentPermissions.has(permission));
};
const roleTemplateActionKey = (role, template) => `${role?.id}:${template?.key}`;
const isApplyingTemplate = (role, template) => applyingTemplateKey.value === roleTemplateActionKey(role, template);
const isTemplateActionDisabled = (role, template) =>
templatesLoading.value || Boolean(applyingTemplateKey.value) || missingTemplatePermissions(role, template).length === 0;
const applyLimitedBackofficeTemplate = async (role, template) => {
const missingPermissions = missingTemplatePermissions(role, template);
const label = templateLabel(template);
if (missingPermissions.length === 0) {
await Swal.fire({
icon: "success",
title: t("roles.templates.up_to_date_title"),
text: t("roles.templates.up_to_date_text", { role: role.name, template: label }),
});
return;
}
const confirmation = await Swal.fire({
icon: "question",
title: t("roles.templates.confirm_title"),
text: t("roles.templates.confirm_text", {
count: missingPermissions.length,
role: role.name,
template: label,
}),
showCancelButton: true,
confirmButtonText: t("roles.templates.confirm_button"),
cancelButtonText: t("common.cancel"),
});
if (!confirmation.isConfirmed) {
return;
}
applyingTemplateKey.value = roleTemplateActionKey(role, template);
try {
const results = await Promise.allSettled(
missingPermissions.map((permission) =>
SessionUser.objects.roles.functions.permissions.add(role.id, permission)
)
);
const failed = results.filter((result) => result.status === "rejected");
if (failed.length > 0) {
throw failed[0].reason;
}
await Swal.fire({
icon: "success",
title: t("roles.templates.success_title"),
text: t("roles.templates.success_text", {
count: missingPermissions.length,
role: role.name,
template: label,
}),
});
} catch (error) {
console.error("Failed to apply limited backoffice permission template", error);
await Swal.fire({
icon: "error",
title: t("roles.templates.error_title"),
text: t("roles.templates.error_text", { role: role.name, template: label }),
});
} finally {
applyingTemplateKey.value = "";
await loadList();
}
};
onMounted(loadLimitedBackofficeTemplates);
</script>
<template>
@@ -66,6 +181,46 @@ const redirect = (path) => {
icon="fas fa-clone"
:click-action="() => SessionUser.objects.roles.functions.cloneObject(object.id).then(() => loadList())"
></ActionSettingsWheelItem>
<div
v-if="canApplyLimitedBackofficeTemplates"
class="role-limited-backoffice-template-actions"
:data-testid="`role-limited-backoffice-template-actions-${object.id}`"
>
<ActionSettingsWheelItemLabel
:label="$t('roles.templates.section')"
icon="fas fa-id-badge"
></ActionSettingsWheelItemLabel>
<ActionSettingsWheelItem
v-if="templatesLoading"
:label="$t('roles.templates.loading')"
icon="fas fa-spinner"
disabled
></ActionSettingsWheelItem>
<ActionSettingsWheelItem
v-else-if="templatesLoadError"
:label="$t('roles.templates.load_error')"
icon="fas fa-sync-alt"
:click-action="loadLimitedBackofficeTemplates"
></ActionSettingsWheelItem>
<ActionSettingsWheelItem
v-else-if="limitedBackofficeTemplates.length === 0"
:label="$t('roles.templates.unavailable')"
icon="fas fa-ban"
disabled
></ActionSettingsWheelItem>
<template v-else>
<ActionSettingsWheelItem
v-for="template in limitedBackofficeTemplates"
:key="template.key"
:label="$t('roles.templates.apply', { template: templateLabel(template) })"
:icon="isApplyingTemplate(object, template) ? 'fas fa-spinner' : 'fas fa-id-badge'"
:disabled="isTemplateActionDisabled(object, template)"
:test-id="`role-template-${object.id}-${template.key}`"
:click-action="() => applyLimitedBackofficeTemplate(object, template)"
></ActionSettingsWheelItem>
</template>
</div>
</template>
</ActionSettingsWheelButton>
</div>
@@ -85,4 +240,4 @@ const redirect = (path) => {
<style scoped>
</style>
</style>
@@ -2,6 +2,14 @@
import ActionSettingsWheelButton from "@/components/displays/buttons/ActionSettingsWheelButton.vue";
import ActionSettingsWheelItem from "@/components/displays/buttons/ActionSettingsWheelItem.vue";
import { showEditUserForm } from "@/components/forms/superUser/editUserForm.vue";
import {
getLimitedBackofficeDepartments,
getLimitedBackofficeRoles,
limitedBackofficeErrorMessage,
migrateLimitedBackofficeEmployee,
unwrapLimitedBackofficeResponse,
} from "@/services/limitedBackoffice.js";
import Swal from "sweetalert2";
defineProps({
objects: {
@@ -10,11 +18,110 @@ defineProps({
},
});
const emit = defineEmits(["migrated"]);
const editUser = (user) => {
showEditUserForm(user.id, user.customer_number, user.display_name, user.group_id, {
limitedBackofficeManaged: Boolean(user.limited_backoffice_managed),
});
};
const escapeHtml = (value) =>
String(value ?? "")
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#039;");
const canMigrateToLimitedBackoffice = (user) =>
Number(user?.customer_number) === 0 && !Boolean(user?.limited_backoffice_managed);
const migrateUser = async (user) => {
try {
const [departmentsResponse, rolesResponse] = await Promise.all([
getLimitedBackofficeDepartments(),
getLimitedBackofficeRoles(),
]);
const departments = unwrapLimitedBackofficeResponse(departmentsResponse) || [];
const roles = unwrapLimitedBackofficeResponse(rolesResponse) || [];
if (!Array.isArray(departments) || departments.length === 0 || !Array.isArray(roles) || roles.length === 0) {
throw new Error("Limited backoffice roles or departments are unavailable.");
}
const roleOptions = roles
.filter((role) => role?.key && role?.key !== "superuser")
.map((role) => {
const selected = role.key === "cashier" ? " selected" : "";
return `<option value="${escapeHtml(role.key)}"${selected}>${escapeHtml(role.label || role.key)}</option>`;
})
.join("");
const departmentOptions = departments
.map(
(department) => `
<label class="checkbox is-block has-text-left mb-2">
<input type="checkbox" class="limited-migration-department" value="${escapeHtml(department.id)}" />
${escapeHtml(department.name || `Department ${department.id}`)}
</label>
`
)
.join("");
const result = await Swal.fire({
title: "Migrate employee",
html: `
<div class="field has-text-left">
<label class="label">Employee</label>
<p>${escapeHtml(user.display_name || `#${user.id}`)}</p>
</div>
<div class="field has-text-left">
<label class="label" for="limited-migration-role">Role</label>
<div class="control">
<div class="select is-fullwidth">
<select id="limited-migration-role">${roleOptions}</select>
</div>
</div>
</div>
<div class="field has-text-left">
<label class="label">Departments</label>
<div class="control">${departmentOptions}</div>
</div>
`,
showCancelButton: true,
confirmButtonText: "Migrate",
preConfirm: async () => {
const role = document.getElementById("limited-migration-role")?.value;
const departmentIds = Array.from(document.querySelectorAll(".limited-migration-department:checked")).map(
(checkbox) => Number(checkbox.value)
);
if (!role || departmentIds.length === 0) {
Swal.showValidationMessage("Select a role and at least one department.");
return false;
}
try {
await migrateLimitedBackofficeEmployee(user.id, {
role_key: role,
department_ids: departmentIds,
});
return true;
} catch (error) {
Swal.showValidationMessage(limitedBackofficeErrorMessage(error, "Could not migrate employee."));
return false;
}
},
});
if (result.isConfirmed) {
await Swal.fire("Employee migrated");
emit("migrated");
}
} catch (error) {
await Swal.fire("Error", limitedBackofficeErrorMessage(error, "Could not migrate employee."), "error");
}
};
</script>
<template>
@@ -47,6 +154,13 @@ const editUser = (user) => {
:label="$t('global.edit')"
:test-id="`superuser-user-edit-${user.id}`"
/>
<ActionSettingsWheelItem
v-if="canMigrateToLimitedBackoffice(user)"
:click-action="() => migrateUser(user)"
icon="fas fa-random"
:label="$t('superuser.pages.employees.migrate_to_limited_backoffice')"
:test-id="`superuser-user-migrate-limited-${user.id}`"
/>
</template>
</ActionSettingsWheelButton>
</div>
@@ -1,5 +1,4 @@
<script>
import Swal from "sweetalert2";
import { authenticatedRequest } from "@/components/session/authenticatedRequest.vue";
import { ObjectsGlobal } from "@/components/session/token/SessionUser/Objects/ObjectsGlobal.vue";
import { SessionUser } from "@/components/session/token/SessionUser.vue";
@@ -123,6 +122,10 @@ export const Roles = {
id: id
});
},
getLimitedBackofficePermissionTemplates: async () => {
const response = await authenticatedRequest("/roles/limited-backoffice-permission-templates", "GET");
return response?.data?.data ?? response?.data ?? [];
},
permissions: {
add: async (roleId, permissionId) => {
return authenticatedRequest("/roles/permissions", "POST", {
@@ -161,4 +164,4 @@ export const Roles = {
);
}
};
</script>
</script>
+150 -3
View File
@@ -1270,6 +1270,11 @@
"groups": {
"account": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -1321,6 +1326,66 @@
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -4983,6 +5048,22 @@
"title": "Tilladelser for rolle {id}",
"title_with_name": "Tilladelser for {name}"
},
"templates": {
"apply": "Anvend {template}-skabelon",
"confirm_button": "Anvend skabelon",
"confirm_text": "Tilfoej {count} manglende tilladelser fra {template} til {role}?",
"confirm_title": "Anvend tilladelsesskabelon?",
"error_text": "En eller flere tilladelser fra {template} kunne ikke tilfoejes til {role}. Rollelisten blev genindlaest.",
"error_title": "Kunne ikke anvende skabelon",
"load_error": "Kunne ikke indlaese skabeloner. Proev igen",
"loading": "Indlaeser skabeloner...",
"section": "Begraenset backoffice-skabeloner",
"success_text": "Tilfoejede {count} tilladelser fra {template} til {role}.",
"success_title": "Skabelon anvendt",
"unavailable": "Ingen skabeloner er tilgaengelige.",
"up_to_date_text": "{role} har allerede alle tilladelser i {template}.",
"up_to_date_title": "Rollen er opdateret"
},
"subtitle": "@.capitalize:{'words.generated.brugerroller'}"
},
"self_wash": {
@@ -5392,6 +5473,7 @@
},
"employees": {
"create": "@:{'words.generated.opret'} @:{'words.generated.ny'} @:{'words.generated.medarbejder'}",
"migrate_to_limited_backoffice": "Migrer til begrænset backoffice",
"subtitle": "@.capitalize:{'words.generated.her'} @:{'words.generated.kan'} @:{'words.generated.du'} @:{'words.generated.se'} @:{'words.replication.host_definite_suffix'} @:{'words.generated.liste'} @:{'words.generated.over'} @:{'words.generated.alle'} @:{'words.generated.medarbejdere'} @:{'words.generated.i'} @:{'words.generated.systemet'}"
},
"orders": {
@@ -6135,12 +6217,12 @@
},
"roles": {
"viewer": {
"label": "Viser",
"description": "@.capitalize:{'words.generated.kan'} logge ind @:{'words.generated.og'} se data @:{'words.generated.for'} @:{'words.generated.tildelte'} @:{'words.generated.afdelinger'}."
"label": "Deaktiveret",
"description": "Holder medarbejderen registreret uden adgang til ordre-, booking- eller administrationsfunktioner."
},
"cashier": {
"label": "Kassemedarbejder",
"description": "@.capitalize:{'words.generated.kan'} arbejde med @:{'words.generated.ordrer'} @:{'words.generated.og'} ordrelinjer @:{'words.generated.for'} @:{'words.generated.tildelte'} @:{'words.generated.afdelinger'}."
"description": "@.capitalize:{'words.generated.kan'} arbejde med @:{'words.generated.ordrer'}, ordrelinjer @:{'words.generated.og'} @:{'words.generated.bookinger'} @:{'words.generated.for'} @:{'words.generated.tildelte'} @:{'words.generated.afdelinger'}."
},
"booking_coordinator": {
"label": "Bookingkoordinator",
@@ -6175,6 +6257,11 @@
"groups": {
"account": "Konto",
"orders": "Ordrer",
"products": "Produkter",
"customers": "Kunder",
"vehicles": "Køretøjer",
"attachments": "Vedhæftninger",
"scanner": "Scannere",
"bookings": "Bookinger",
"time_bookings": "Tidsbookinger",
"reports": "Rapporter",
@@ -6226,6 +6313,66 @@
"label": "Opkræv ordrer",
"description": "Kan tage betaling eller opkræve en betalingsreservation for en ordre."
},
"complete_orders": {
"label": "Afslut ordrer",
"description": "Kan markere ordrer som afsluttede."
},
"view_product_catalog": {
"label": "Se produktkatalog",
"description": "Kan indlæse POS-kategorier, produkter, priser og tilvalg."
},
"view_product_recommendations": {
"label": "Se produktforslag",
"description": "Kan se produktforslag baseret på ordrer og køretøjsdata."
},
"search_customers": {
"label": "Søg kunder",
"description": "Kan søge og vælge kunder til POS-ordrer."
},
"view_customer_details": {
"label": "Se kundeoplysninger",
"description": "Kan indlæse kundeoplysninger fra et kundenummer."
},
"view_customer_notes": {
"label": "Se kundebemærkninger",
"description": "Kan læse kundebemærkninger i POS."
},
"add_customer_notes": {
"label": "Tilføj kundebemærkninger",
"description": "Kan tilføje kundebemærkninger fra POS."
},
"view_customer_flags": {
"label": "Se kundemarkeringer",
"description": "Kan se kundemarkeringer, der påvirker ordrekrav og produktregler."
},
"search_vehicles": {
"label": "Søg køretøjer",
"description": "Kan søge nummerplader og se køretøjsstatus."
},
"view_vehicle_matches": {
"label": "Se køretøjsmatch",
"description": "Kan se kundematch for køretøjer og forslag til ukendte køretøjer."
},
"view_vehicle_history": {
"label": "Se køretøjshistorik",
"description": "Kan se seneste ordrehistorik for en nummerplade."
},
"view_order_attachments": {
"label": "Se ordrevedhæftninger",
"description": "Kan liste vedhæftninger på ordrer."
},
"add_order_attachments": {
"label": "Tilføj ordrevedhæftninger",
"description": "Kan uploade filer og vedhæfte vaskecertifikater til ordrer."
},
"download_order_attachments": {
"label": "Download ordrevedhæftninger",
"description": "Kan åbne og downloade ordrevedhæftninger."
},
"view_plate_scans": {
"label": "Se nummerpladescanninger",
"description": "Kan se seneste nummerpladescanninger og scannere for tildelte afdelinger."
},
"view_department_bookings": {
"label": "Se afdelingsbookinger",
"description": "Kan se bookinger for tildelte afdelinger."
+150 -3
View File
@@ -1381,6 +1381,11 @@
"groups": {
"account": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -1432,6 +1437,66 @@
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -5094,6 +5159,22 @@
"title": "Berechtigungen fuer Rolle {id}",
"title_with_name": "Berechtigungen fuer {name}"
},
"templates": {
"apply": "{template}-Vorlage anwenden",
"confirm_button": "Vorlage anwenden",
"confirm_text": "{count} fehlende Berechtigungen aus {template} zu {role} hinzufuegen?",
"confirm_title": "Berechtigungsvorlage anwenden?",
"error_text": "Eine oder mehrere Berechtigungen aus {template} konnten {role} nicht hinzugefuegt werden. Die Rollenliste wurde neu geladen.",
"error_title": "Vorlage konnte nicht angewendet werden",
"load_error": "Vorlagen konnten nicht geladen werden. Erneut versuchen",
"loading": "Vorlagen werden geladen...",
"section": "Limited-Backoffice-Vorlagen",
"success_text": "{count} Berechtigungen aus {template} zu {role} hinzugefuegt.",
"success_title": "Vorlage angewendet",
"unavailable": "Keine Vorlagen verfuegbar.",
"up_to_date_text": "{role} hat bereits alle Berechtigungen in {template}.",
"up_to_date_title": "Rolle ist aktuell"
},
"subtitle": "Benutzerrollen"
},
"self_wash": {
@@ -5503,6 +5584,7 @@
},
"employees": {
"create": "@.capitalize:{'words.generated.neuen'} @:{'words.generated.mitarbeiter'} @:{'words.generated.erstellen'}",
"migrate_to_limited_backoffice": "Zu eingeschränktem Backoffice migrieren",
"subtitle": "@.capitalize:{'words.generated.hier'} @:{'words.generated.sehen'} @.capitalize:{'words.generated.sie'} @:{'words.generated.eine'} @:{'words.generated.liste'} @:{'words.generated.aller'} @:{'words.generated.mitarbeiter'} @:{'words.generated.im'} @.capitalize:{'words.generated.system'}"
},
"orders": {
@@ -6246,12 +6328,12 @@
},
"roles": {
"viewer": {
"label": "Betrachter",
"description": "@.capitalize:{'words.generated.kann'} sich anmelden @:{'words.generated.und'} Daten zugewiesener @:{'words.generated.abteilungen'} @:{'words.generated.anzeigen'}."
"label": "Deaktiviert",
"description": "Hält den Mitarbeiter registriert, ohne Zugriff auf Auftrags-, Buchungs- oder Verwaltungsfunktionen."
},
"cashier": {
"label": "Kassierer",
"description": "@.capitalize:{'words.generated.kann'} mit Aufträgen @:{'words.generated.und'} Auftragszeilen @:{'words.generated.fur'} @:{'words.generated.zugewiesene'} @:{'words.generated.abteilungen'} arbeiten."
"description": "@.capitalize:{'words.generated.kann'} mit Aufträgen, Auftragszeilen @:{'words.generated.und'} @:{'words.generated.buchungen'} @:{'words.generated.fur'} @:{'words.generated.zugewiesene'} @:{'words.generated.abteilungen'} arbeiten."
},
"booking_coordinator": {
"label": "Buchungskoordinator",
@@ -6286,6 +6368,11 @@
"groups": {
"account": "Konto",
"orders": "Aufträge",
"products": "Produkte",
"customers": "Kunden",
"vehicles": "Fahrzeuge",
"attachments": "Anhänge",
"scanner": "Scanner",
"bookings": "Buchungen",
"time_bookings": "Zeitbuchungen",
"reports": "Berichte",
@@ -6337,6 +6424,66 @@
"label": "Aufträge abrechnen",
"description": "Kann Zahlungen annehmen oder eine Zahlungsreservierung für einen Auftrag belasten."
},
"complete_orders": {
"label": "Aufträge abschließen",
"description": "Kann Aufträge als abgeschlossen markieren."
},
"view_product_catalog": {
"label": "Produktkatalog anzeigen",
"description": "Kann POS-Kategorien, Produkte, Preise und Zusatzoptionen laden."
},
"view_product_recommendations": {
"label": "Produktempfehlungen anzeigen",
"description": "Kann Produktempfehlungen auf Basis von Aufträgen und Fahrzeugdaten sehen."
},
"search_customers": {
"label": "Kunden suchen",
"description": "Kann Kunden für POS-Aufträge suchen und auswählen."
},
"view_customer_details": {
"label": "Kundendetails anzeigen",
"description": "Kann Kundendetails anhand einer Kundennummer laden."
},
"view_customer_notes": {
"label": "Kundennotizen anzeigen",
"description": "Kann Kundennotizen im POS lesen."
},
"add_customer_notes": {
"label": "Kundennotizen hinzufügen",
"description": "Kann Kundennotizen im POS hinzufügen."
},
"view_customer_flags": {
"label": "Kundenmarkierungen anzeigen",
"description": "Kann Kundenmarkierungen sehen, die Auftragsanforderungen und Produktregeln beeinflussen."
},
"search_vehicles": {
"label": "Fahrzeuge suchen",
"description": "Kann Kennzeichen suchen und den Fahrzeugstatus sehen."
},
"view_vehicle_matches": {
"label": "Fahrzeugtreffer anzeigen",
"description": "Kann Kundentreffer für Fahrzeuge und Vorschläge zu unbekannten Fahrzeugen sehen."
},
"view_vehicle_history": {
"label": "Fahrzeughistorie anzeigen",
"description": "Kann die letzte Auftragshistorie für ein Kennzeichen sehen."
},
"view_order_attachments": {
"label": "Auftragsanhänge anzeigen",
"description": "Kann Anhänge auf Aufträgen auflisten."
},
"add_order_attachments": {
"label": "Auftragsanhänge hinzufügen",
"description": "Kann Dateien hochladen und Waschzertifikate an Aufträge anhängen."
},
"download_order_attachments": {
"label": "Auftragsanhänge herunterladen",
"description": "Kann Auftragsanhänge öffnen und herunterladen."
},
"view_plate_scans": {
"label": "Kennzeichenscans anzeigen",
"description": "Kann aktuelle Kennzeichenscans und Scanner für zugewiesene Abteilungen sehen."
},
"view_department_bookings": {
"label": "Abteilungsbuchungen anzeigen",
"description": "Kann Buchungen für zugewiesene Abteilungen sehen."
+150 -3
View File
@@ -1102,6 +1102,11 @@
"groups": {
"account": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -1153,6 +1158,66 @@
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -4815,6 +4880,22 @@
"title": "Role {id} permissions",
"title_with_name": "{name} permissions"
},
"templates": {
"apply": "Apply {template} template",
"confirm_button": "Apply template",
"confirm_text": "Add {count} missing permissions from {template} to {role}?",
"confirm_title": "Apply permission template?",
"error_text": "One or more permissions from {template} could not be added to {role}. The role list was reloaded.",
"error_title": "Could not apply template",
"load_error": "Could not load templates. Try again",
"loading": "Loading templates...",
"section": "Limited backoffice templates",
"success_text": "Added {count} permissions from {template} to {role}.",
"success_title": "Template applied",
"unavailable": "No templates are available.",
"up_to_date_text": "{role} already has every permission in {template}.",
"up_to_date_title": "Role is up to date"
},
"subtitle": "@.capitalize:{'words.generated.user'} @:{'words.generated.roles'}"
},
"self_wash": {
@@ -5224,6 +5305,7 @@
},
"employees": {
"create": "@.capitalize:{'words.generated.create'} @:{'words.generated.new'} @:{'words.generated.employee'}",
"migrate_to_limited_backoffice": "Migrate to limited backoffice",
"subtitle": "@.capitalize:{'words.generated.here'} @:{'words.generated.you'} @:{'words.generated.can'} @:{'words.generated.see'} @:{'words.generated.a'} @:{'words.generated.list'} @:{'words.generated.of'} @:{'words.generated.all'} @:{'words.generated.employees'} @:{'words.generated.in'} @:{'words.replication.article.host_mention'} @:{'words.generated.system'}"
},
"orders": {
@@ -5967,12 +6049,12 @@
},
"roles": {
"viewer": {
"label": "Viewer",
"description": "@.capitalize:{'words.generated.can'} sign @:{'words.generated.in'} @:{'words.generated.and'} view @:{'words.generated.assigned'} @:{'words.generated.department'} data."
"label": "Deactivated",
"description": "Keeps the employee registered without order, booking, or management permissions."
},
"cashier": {
"label": "Cashier",
"description": "@.capitalize:{'words.generated.can'} work with @:{'words.generated.orders'} @:{'words.generated.and'} order lines @:{'words.generated.for'} @:{'words.generated.assigned'} @:{'words.generated.departments'}."
"description": "@.capitalize:{'words.generated.can'} work with @:{'words.generated.orders'}, order lines @:{'words.generated.and'} @:{'words.generated.bookings'} @:{'words.generated.for'} @:{'words.generated.assigned'} @:{'words.generated.departments'}."
},
"booking_coordinator": {
"label": "Booking coordinator",
@@ -6007,6 +6089,11 @@
"groups": {
"account": "Account",
"orders": "Orders",
"products": "Products",
"customers": "Customers",
"vehicles": "Vehicles",
"attachments": "Attachments",
"scanner": "Scanners",
"bookings": "Bookings",
"time_bookings": "Time bookings",
"reports": "Reports",
@@ -6058,6 +6145,66 @@
"label": "Charge orders",
"description": "Can take payment or charge a payment intent for an order."
},
"complete_orders": {
"label": "Complete orders",
"description": "Can mark orders as completed."
},
"view_product_catalog": {
"label": "View product catalog",
"description": "Can load POS categories, products, prices, and addons."
},
"view_product_recommendations": {
"label": "View product recommendations",
"description": "Can see product suggestions based on orders and vehicle data."
},
"search_customers": {
"label": "Search customers",
"description": "Can search and select customers for POS orders."
},
"view_customer_details": {
"label": "View customer details",
"description": "Can load customer details from a customer number."
},
"view_customer_notes": {
"label": "View customer notes",
"description": "Can read customer notes in POS."
},
"add_customer_notes": {
"label": "Add customer notes",
"description": "Can add customer notes from POS."
},
"view_customer_flags": {
"label": "View customer flags",
"description": "Can see customer flags that affect order requirements and product rules."
},
"search_vehicles": {
"label": "Search vehicles",
"description": "Can search license plates and see vehicle status."
},
"view_vehicle_matches": {
"label": "View vehicle matches",
"description": "Can see vehicle customer matches and unknown vehicle suggestions."
},
"view_vehicle_history": {
"label": "View vehicle history",
"description": "Can see recent order history for a license plate."
},
"view_order_attachments": {
"label": "View order attachments",
"description": "Can list attachments on orders."
},
"add_order_attachments": {
"label": "Add order attachments",
"description": "Can upload files and attach wash certificates to orders."
},
"download_order_attachments": {
"label": "Download order attachments",
"description": "Can open and download order attachments."
},
"view_plate_scans": {
"label": "View plate scans",
"description": "Can view recent license plate scans and scanners for assigned departments."
},
"view_department_bookings": {
"label": "View department bookings",
"description": "Can see bookings for assigned departments."
+16
View File
@@ -4373,6 +4373,22 @@
"title": "@:{'templates.generated.compat.roles.permissions.title'}",
"title_with_name": "@:{'templates.generated.compat.roles.permissions.title_with_name'}"
},
"templates": {
"apply": "@:{'templates.generated.compat.roles.templates.apply'}",
"confirm_button": "@:{'templates.generated.compat.roles.templates.confirm_button'}",
"confirm_text": "@:{'templates.generated.compat.roles.templates.confirm_text'}",
"confirm_title": "@:{'templates.generated.compat.roles.templates.confirm_title'}",
"error_text": "@:{'templates.generated.compat.roles.templates.error_text'}",
"error_title": "@:{'templates.generated.compat.roles.templates.error_title'}",
"load_error": "@:{'templates.generated.compat.roles.templates.load_error'}",
"loading": "@:{'templates.generated.compat.roles.templates.loading'}",
"section": "@:{'templates.generated.compat.roles.templates.section'}",
"success_text": "@:{'templates.generated.compat.roles.templates.success_text'}",
"success_title": "@:{'templates.generated.compat.roles.templates.success_title'}",
"unavailable": "@:{'templates.generated.compat.roles.templates.unavailable'}",
"up_to_date_text": "@:{'templates.generated.compat.roles.templates.up_to_date_text'}",
"up_to_date_title": "@:{'templates.generated.compat.roles.templates.up_to_date_title'}"
},
"subtitle": "@:{'templates.generated.compat.roles.subtitle'}",
"title": "@:{'templates.generated.compat.common.roles'}"
},
+150 -3
View File
@@ -1384,6 +1384,11 @@
"groups": {
"account": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -1435,6 +1440,66 @@
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -5097,6 +5162,22 @@
"title": "Tillatelser for rolle {id}",
"title_with_name": "Tillatelser for {name}"
},
"templates": {
"apply": "Bruk {template}-mal",
"confirm_button": "Bruk mal",
"confirm_text": "Legg til {count} manglende tillatelser fra {template} til {role}?",
"confirm_title": "Bruke tillatelsesmal?",
"error_text": "En eller flere tillatelser fra {template} kunne ikke legges til i {role}. Rollelisten ble lastet inn pa nytt.",
"error_title": "Kunne ikke bruke mal",
"load_error": "Kunne ikke laste maler. Prov igjen",
"loading": "Laster maler...",
"section": "Begrenset backoffice-maler",
"success_text": "La til {count} tillatelser fra {template} i {role}.",
"success_title": "Mal brukt",
"unavailable": "Ingen maler er tilgjengelige.",
"up_to_date_text": "{role} har allerede alle tillatelser i {template}.",
"up_to_date_title": "Rollen er oppdatert"
},
"subtitle": "@.capitalize:{'words.generated.user'} roles"
},
"self_wash": {
@@ -5506,6 +5587,7 @@
},
"employees": {
"create": "@:{'words.generated.opprett'} @:{'words.generated.ny'} medarbeider",
"migrate_to_limited_backoffice": "Migrer til begrenset backoffice",
"subtitle": "@.capitalize:{'words.generated.her'} @:{'words.generated.kan'} @:{'words.generated.du'} @:{'words.generated.se'} @:{'words.replication.host_definite_suffix'} @:{'words.generated.liste'} @:{'words.generated.over'} @:{'words.generated.alle'} @:{'words.generated.ansatte'} @:{'words.generated.i'} @:{'words.generated.systemet'}"
},
"orders": {
@@ -6249,12 +6331,12 @@
},
"roles": {
"viewer": {
"label": "Viser",
"description": "@.capitalize:{'words.generated.kan'} logge inn @:{'words.generated.og'} se data @:{'words.generated.for'} @:{'words.generated.tildelte'} @:{'words.generated.avdelinger'}."
"label": "Deaktivert",
"description": "Holder den ansatte registrert uten tilgang til ordre-, booking- eller administrasjonsfunksjoner."
},
"cashier": {
"label": "Kasserer",
"description": "@.capitalize:{'words.generated.kan'} arbeide med @:{'words.generated.ordre'} @:{'words.generated.og'} ordrelinjer @:{'words.generated.for'} @:{'words.generated.tildelte'} @:{'words.generated.avdelinger'}."
"description": "@.capitalize:{'words.generated.kan'} arbeide med @:{'words.generated.ordre'}, ordrelinjer @:{'words.generated.og'} @:{'words.generated.bookinger'} @:{'words.generated.for'} @:{'words.generated.tildelte'} @:{'words.generated.avdelinger'}."
},
"booking_coordinator": {
"label": "Bookingkoordinator",
@@ -6289,6 +6371,11 @@
"groups": {
"account": "Konto",
"orders": "Ordrer",
"products": "Produkter",
"customers": "Kunder",
"vehicles": "Kjøretøy",
"attachments": "Vedlegg",
"scanner": "Skannere",
"bookings": "Bookinger",
"time_bookings": "Tidsbookinger",
"reports": "Rapporter",
@@ -6340,6 +6427,66 @@
"label": "Belast ordrer",
"description": "Kan ta betaling eller belaste en betalingsreservasjon for en ordre."
},
"complete_orders": {
"label": "Fullfør ordrer",
"description": "Kan markere ordrer som fullført."
},
"view_product_catalog": {
"label": "Se produktkatalog",
"description": "Kan laste POS-kategorier, produkter, priser og tillegg."
},
"view_product_recommendations": {
"label": "Se produktforslag",
"description": "Kan se produktforslag basert på ordrer og kjøretøydata."
},
"search_customers": {
"label": "Søk kunder",
"description": "Kan søke og velge kunder for POS-ordrer."
},
"view_customer_details": {
"label": "Se kundeopplysninger",
"description": "Kan laste kundeopplysninger fra et kundenummer."
},
"view_customer_notes": {
"label": "Se kundemerknader",
"description": "Kan lese kundemerknader i POS."
},
"add_customer_notes": {
"label": "Legg til kundemerknader",
"description": "Kan legge til kundemerknader fra POS."
},
"view_customer_flags": {
"label": "Se kundemarkeringer",
"description": "Kan se kundemarkeringer som påvirker ordrekrav og produktregler."
},
"search_vehicles": {
"label": "Søk kjøretøy",
"description": "Kan søke etter registreringsnummer og se kjøretøystatus."
},
"view_vehicle_matches": {
"label": "Se kjøretøytreff",
"description": "Kan se kundetreff for kjøretøy og forslag til ukjente kjøretøy."
},
"view_vehicle_history": {
"label": "Se kjøretøyhistorikk",
"description": "Kan se nylig ordrehistorikk for et registreringsnummer."
},
"view_order_attachments": {
"label": "Se ordrevedlegg",
"description": "Kan liste vedlegg på ordrer."
},
"add_order_attachments": {
"label": "Legg til ordrevedlegg",
"description": "Kan laste opp filer og legge ved vaskesertifikater på ordrer."
},
"download_order_attachments": {
"label": "Last ned ordrevedlegg",
"description": "Kan åpne og laste ned ordrevedlegg."
},
"view_plate_scans": {
"label": "Se nummerskiltskanninger",
"description": "Kan se nylige nummerskiltskanninger og skannere for tildelte avdelinger."
},
"view_department_bookings": {
"label": "Se avdelingsbookinger",
"description": "Kan se bookinger for tildelte avdelinger."
+150 -3
View File
@@ -1434,6 +1434,11 @@
"groups": {
"account": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'templates.generated.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -1485,6 +1490,66 @@
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'templates.generated.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -5147,6 +5212,22 @@
"title": "Behorigheter for roll {id}",
"title_with_name": "Behorigheter for {name}"
},
"templates": {
"apply": "Anvand mallen {template}",
"confirm_button": "Anvand mall",
"confirm_text": "Lagg till {count} saknade behorigheter fran {template} till {role}?",
"confirm_title": "Anvanda behorighetsmall?",
"error_text": "En eller flera behorigheter fran {template} kunde inte laggas till i {role}. Rolllistan laddades om.",
"error_title": "Kunde inte anvanda mall",
"load_error": "Kunde inte ladda mallar. Forsok igen",
"loading": "Laddar mallar...",
"section": "Begransade backoffice-mallar",
"success_text": "Lade till {count} behorigheter fran {template} i {role}.",
"success_title": "Mall anvand",
"unavailable": "Inga mallar ar tillgangliga.",
"up_to_date_text": "{role} har redan alla behorigheter i {template}.",
"up_to_date_title": "Rollen ar uppdaterad"
},
"subtitle": "@.capitalize:{'words.generated.user'} @:{'words.generated.roles'}"
},
"self_wash": {
@@ -5556,6 +5637,7 @@
},
"employees": {
"create": "@.capitalize:{'words.generated.skapa'} @:{'words.generated.ny'} @:{'words.generated.anstalld'}",
"migrate_to_limited_backoffice": "Migrera till begränsad backoffice",
"subtitle": "@.capitalize:{'words.generated.har_2'} @:{'words.generated.kan'} @:{'words.generated.du'} @:{'words.generated.se'} @:{'words.replication.host_definite_suffix'} @:{'words.generated.lista'} @:{'words.generated.over'} @:{'words.generated.alla'} @:{'words.generated.anstallda'} @:{'words.generated.i'} @:{'words.generated.systemet'}"
},
"orders": {
@@ -6299,12 +6381,12 @@
},
"roles": {
"viewer": {
"label": "Visare",
"description": "@.capitalize:{'words.generated.kan'} logga in @:{'words.generated.och'} se data @:{'words.generated.for'} @:{'words.generated.tilldelade'} @:{'words.generated.avdelningar'}."
"label": "Inaktiverad",
"description": "Behåller medarbetaren registrerad utan åtkomst till order-, boknings- eller administrationsfunktioner."
},
"cashier": {
"label": "Kassör",
"description": "@.capitalize:{'words.generated.kan'} arbeta med @:{'words.generated.order'} @:{'words.generated.och'} orderrader @:{'words.generated.for'} @:{'words.generated.tilldelade'} @:{'words.generated.avdelningar'}."
"description": "@.capitalize:{'words.generated.kan'} arbeta med @:{'words.generated.order'}, orderrader @:{'words.generated.och'} @:{'words.generated.bokningar'} @:{'words.generated.for'} @:{'words.generated.tilldelade'} @:{'words.generated.avdelningar'}."
},
"booking_coordinator": {
"label": "Bokningskoordinator",
@@ -6339,6 +6421,11 @@
"groups": {
"account": "Konto",
"orders": "Order",
"products": "Produkter",
"customers": "Kunder",
"vehicles": "Fordon",
"attachments": "Bilagor",
"scanner": "Skannrar",
"bookings": "Bokningar",
"time_bookings": "Tidsbokningar",
"reports": "Rapporter",
@@ -6390,6 +6477,66 @@
"label": "Debitera order",
"description": "Kan ta betalt eller debitera en betalningsreservation för en order."
},
"complete_orders": {
"label": "Slutför ordrar",
"description": "Kan markera ordrar som slutförda."
},
"view_product_catalog": {
"label": "Visa produktkatalog",
"description": "Kan läsa in POS-kategorier, produkter, priser och tillval."
},
"view_product_recommendations": {
"label": "Visa produktförslag",
"description": "Kan se produktförslag baserade på ordrar och fordonsdata."
},
"search_customers": {
"label": "Sök kunder",
"description": "Kan söka och välja kunder för POS-ordrar."
},
"view_customer_details": {
"label": "Visa kunduppgifter",
"description": "Kan läsa in kunduppgifter från ett kundnummer."
},
"view_customer_notes": {
"label": "Visa kundanteckningar",
"description": "Kan läsa kundanteckningar i POS."
},
"add_customer_notes": {
"label": "Lägg till kundanteckningar",
"description": "Kan lägga till kundanteckningar från POS."
},
"view_customer_flags": {
"label": "Visa kundmarkeringar",
"description": "Kan se kundmarkeringar som påverkar orderkrav och produktregler."
},
"search_vehicles": {
"label": "Sök fordon",
"description": "Kan söka registreringsnummer och se fordonsstatus."
},
"view_vehicle_matches": {
"label": "Visa fordonsträffar",
"description": "Kan se kundträffar för fordon och förslag på okända fordon."
},
"view_vehicle_history": {
"label": "Visa fordonshistorik",
"description": "Kan se senaste orderhistorik för ett registreringsnummer."
},
"view_order_attachments": {
"label": "Visa orderbilagor",
"description": "Kan lista bilagor på ordrar."
},
"add_order_attachments": {
"label": "Lägg till orderbilagor",
"description": "Kan ladda upp filer och bifoga tvättcertifikat till ordrar."
},
"download_order_attachments": {
"label": "Ladda ner orderbilagor",
"description": "Kan öppna och ladda ner orderbilagor."
},
"view_plate_scans": {
"label": "Visa nummerskyltsavläsningar",
"description": "Kan se senaste nummerskyltsavläsningar och skannrar för tilldelade avdelningar."
},
"view_department_bookings": {
"label": "Se avdelningsbokningar",
"description": "Kan se bokningar för tilldelade avdelningar."
@@ -91,6 +91,22 @@
"subtitle": "Rolletilladelser",
"title": "Tilladelser for rolle {id}",
"title_with_name": "Tilladelser for {name}"
},
"templates": {
"apply": "Anvend {template}-skabelon",
"confirm_button": "Anvend skabelon",
"confirm_text": "Tilfoej {count} manglende tilladelser fra {template} til {role}?",
"confirm_title": "Anvend tilladelsesskabelon?",
"error_text": "En eller flere tilladelser fra {template} kunne ikke tilfoejes til {role}. Rollelisten blev genindlaest.",
"error_title": "Kunne ikke anvende skabelon",
"load_error": "Kunne ikke indlaese skabeloner. Proev igen",
"loading": "Indlaeser skabeloner...",
"section": "Begraenset backoffice-skabeloner",
"success_text": "Tilfoejede {count} tilladelser fra {template} til {role}.",
"success_title": "Skabelon anvendt",
"unavailable": "Ingen skabeloner er tilgaengelige.",
"up_to_date_text": "{role} har allerede alle tilladelser i {template}.",
"up_to_date_title": "Rollen er opdateret"
}
}
}
@@ -78,6 +78,7 @@
},
"employees": {
"create": "@:{'terms.glossary.opret'} @:{'terms.glossary.ny'} @:{'terms.glossary.medarbejder'}",
"migrate_to_limited_backoffice": "Migrer til begrænset backoffice",
"subtitle": "@.capitalize:{'terms.glossary.her'} @:{'terms.glossary.kan'} @:{'terms.glossary.du'} @:{'terms.glossary.se'} @:{'terms.replication.host_definite_suffix'} @:{'terms.glossary.liste'} @:{'terms.glossary.over'} @:{'terms.glossary.alle'} @:{'terms.glossary.medarbejdere'} @:{'terms.glossary.i'} @:{'terms.glossary.systemet'}"
},
"orders": {
+143 -13
View File
@@ -28,16 +28,16 @@
"title": "@:{'phrases.compat.limited_backoffice.forbidden.title'}",
"department": "@:{'phrases.compat.limited_backoffice.forbidden.department'}"
},
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"setup_required_title": "@:{'phrases.compat.limited_backoffice.prices.setup_required_title'}",
"setup_required_message": "@:{'phrases.compat.limited_backoffice.prices.setup_required_message'}",
"no_products": "@:{'phrases.compat.limited_backoffice.prices.no_products'}"
@@ -126,6 +126,11 @@
"groups": {
"account": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -177,6 +182,66 @@
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -338,12 +403,12 @@
},
"roles": {
"viewer": {
"label": "Viser",
"description": "@.capitalize:{'terms.glossary.kan'} logge ind @:{'terms.glossary.og'} se data @:{'terms.glossary.for'} @:{'terms.glossary.tildelte'} @:{'terms.glossary.afdelinger'}."
"label": "Deaktiveret",
"description": "Holder medarbejderen registreret uden adgang til ordre-, booking- eller administrationsfunktioner."
},
"cashier": {
"label": "Kassemedarbejder",
"description": "@.capitalize:{'terms.glossary.kan'} arbejde med @:{'terms.glossary.ordrer'} @:{'terms.glossary.og'} ordrelinjer @:{'terms.glossary.for'} @:{'terms.glossary.tildelte'} @:{'terms.glossary.afdelinger'}."
"description": "@.capitalize:{'terms.glossary.kan'} arbejde med @:{'terms.glossary.ordrer'}, ordrelinjer @:{'terms.glossary.og'} @:{'terms.glossary.bookinger'} @:{'terms.glossary.for'} @:{'terms.glossary.tildelte'} @:{'terms.glossary.afdelinger'}."
},
"booking_coordinator": {
"label": "Bookingkoordinator",
@@ -378,6 +443,11 @@
"groups": {
"account": "Konto",
"orders": "Ordrer",
"products": "Produkter",
"customers": "Kunder",
"vehicles": "Køretøjer",
"attachments": "Vedhæftninger",
"scanner": "Scannere",
"bookings": "Bookinger",
"time_bookings": "Tidsbookinger",
"reports": "Rapporter",
@@ -429,6 +499,66 @@
"label": "Opkræv ordrer",
"description": "Kan tage betaling eller opkræve en betalingsreservation for en ordre."
},
"complete_orders": {
"label": "Afslut ordrer",
"description": "Kan markere ordrer som afsluttede."
},
"view_product_catalog": {
"label": "Se produktkatalog",
"description": "Kan indlæse POS-kategorier, produkter, priser og tilvalg."
},
"view_product_recommendations": {
"label": "Se produktforslag",
"description": "Kan se produktforslag baseret på ordrer og køretøjsdata."
},
"search_customers": {
"label": "Søg kunder",
"description": "Kan søge og vælge kunder til POS-ordrer."
},
"view_customer_details": {
"label": "Se kundeoplysninger",
"description": "Kan indlæse kundeoplysninger fra et kundenummer."
},
"view_customer_notes": {
"label": "Se kundebemærkninger",
"description": "Kan læse kundebemærkninger i POS."
},
"add_customer_notes": {
"label": "Tilføj kundebemærkninger",
"description": "Kan tilføje kundebemærkninger fra POS."
},
"view_customer_flags": {
"label": "Se kundemarkeringer",
"description": "Kan se kundemarkeringer, der påvirker ordrekrav og produktregler."
},
"search_vehicles": {
"label": "Søg køretøjer",
"description": "Kan søge nummerplader og se køretøjsstatus."
},
"view_vehicle_matches": {
"label": "Se køretøjsmatch",
"description": "Kan se kundematch for køretøjer og forslag til ukendte køretøjer."
},
"view_vehicle_history": {
"label": "Se køretøjshistorik",
"description": "Kan se seneste ordrehistorik for en nummerplade."
},
"view_order_attachments": {
"label": "Se ordrevedhæftninger",
"description": "Kan liste vedhæftninger på ordrer."
},
"add_order_attachments": {
"label": "Tilføj ordrevedhæftninger",
"description": "Kan uploade filer og vedhæfte vaskecertifikater til ordrer."
},
"download_order_attachments": {
"label": "Download ordrevedhæftninger",
"description": "Kan åbne og downloade ordrevedhæftninger."
},
"view_plate_scans": {
"label": "Se nummerpladescanninger",
"description": "Kan se seneste nummerpladescanninger og scannere for tildelte afdelinger."
},
"view_department_bookings": {
"label": "Se afdelingsbookinger",
"description": "Kan se bookinger for tildelte afdelinger."
@@ -91,6 +91,22 @@
"subtitle": "Rollenberechtigungen",
"title": "Berechtigungen fuer Rolle {id}",
"title_with_name": "Berechtigungen fuer {name}"
},
"templates": {
"apply": "{template}-Vorlage anwenden",
"confirm_button": "Vorlage anwenden",
"confirm_text": "{count} fehlende Berechtigungen aus {template} zu {role} hinzufuegen?",
"confirm_title": "Berechtigungsvorlage anwenden?",
"error_text": "Eine oder mehrere Berechtigungen aus {template} konnten {role} nicht hinzugefuegt werden. Die Rollenliste wurde neu geladen.",
"error_title": "Vorlage konnte nicht angewendet werden",
"load_error": "Vorlagen konnten nicht geladen werden. Erneut versuchen",
"loading": "Vorlagen werden geladen...",
"section": "Limited-Backoffice-Vorlagen",
"success_text": "{count} Berechtigungen aus {template} zu {role} hinzugefuegt.",
"success_title": "Vorlage angewendet",
"unavailable": "Keine Vorlagen verfuegbar.",
"up_to_date_text": "{role} hat bereits alle Berechtigungen in {template}.",
"up_to_date_title": "Rolle ist aktuell"
}
}
}
@@ -78,6 +78,7 @@
},
"employees": {
"create": "@.capitalize:{'terms.glossary.neuen'} @:{'terms.glossary.mitarbeiter'} @:{'terms.glossary.erstellen'}",
"migrate_to_limited_backoffice": "Zu eingeschränktem Backoffice migrieren",
"subtitle": "@.capitalize:{'terms.glossary.hier'} @:{'terms.glossary.sehen'} @.capitalize:{'terms.glossary.sie'} @:{'terms.glossary.eine'} @:{'terms.glossary.liste'} @:{'terms.glossary.aller'} @:{'terms.glossary.mitarbeiter'} @:{'terms.glossary.im'} @.capitalize:{'terms.glossary.system'}"
},
"orders": {
+143 -13
View File
@@ -28,16 +28,16 @@
"title": "@:{'phrases.compat.limited_backoffice.forbidden.title'}",
"department": "@:{'phrases.compat.limited_backoffice.forbidden.department'}"
},
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"setup_required_title": "@:{'phrases.compat.limited_backoffice.prices.setup_required_title'}",
"setup_required_message": "@:{'phrases.compat.limited_backoffice.prices.setup_required_message'}",
"no_products": "@:{'phrases.compat.limited_backoffice.prices.no_products'}"
@@ -126,6 +126,11 @@
"groups": {
"account": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -177,6 +182,66 @@
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -338,12 +403,12 @@
},
"roles": {
"viewer": {
"label": "Betrachter",
"description": "@.capitalize:{'terms.glossary.kann'} sich anmelden @:{'terms.glossary.und'} Daten zugewiesener @:{'terms.glossary.abteilungen'} @:{'terms.glossary.anzeigen'}."
"label": "Deaktiviert",
"description": "Hält den Mitarbeiter registriert, ohne Zugriff auf Auftrags-, Buchungs- oder Verwaltungsfunktionen."
},
"cashier": {
"label": "Kassierer",
"description": "@.capitalize:{'terms.glossary.kann'} mit Aufträgen @:{'terms.glossary.und'} Auftragszeilen @:{'terms.glossary.fur'} @:{'terms.glossary.zugewiesene'} @:{'terms.glossary.abteilungen'} arbeiten."
"description": "@.capitalize:{'terms.glossary.kann'} mit Aufträgen, Auftragszeilen @:{'terms.glossary.und'} @:{'terms.glossary.buchungen'} @:{'terms.glossary.fur'} @:{'terms.glossary.zugewiesene'} @:{'terms.glossary.abteilungen'} arbeiten."
},
"booking_coordinator": {
"label": "Buchungskoordinator",
@@ -378,6 +443,11 @@
"groups": {
"account": "Konto",
"orders": "Aufträge",
"products": "Produkte",
"customers": "Kunden",
"vehicles": "Fahrzeuge",
"attachments": "Anhänge",
"scanner": "Scanner",
"bookings": "Buchungen",
"time_bookings": "Zeitbuchungen",
"reports": "Berichte",
@@ -429,6 +499,66 @@
"label": "Aufträge abrechnen",
"description": "Kann Zahlungen annehmen oder eine Zahlungsreservierung für einen Auftrag belasten."
},
"complete_orders": {
"label": "Aufträge abschließen",
"description": "Kann Aufträge als abgeschlossen markieren."
},
"view_product_catalog": {
"label": "Produktkatalog anzeigen",
"description": "Kann POS-Kategorien, Produkte, Preise und Zusatzoptionen laden."
},
"view_product_recommendations": {
"label": "Produktempfehlungen anzeigen",
"description": "Kann Produktempfehlungen auf Basis von Aufträgen und Fahrzeugdaten sehen."
},
"search_customers": {
"label": "Kunden suchen",
"description": "Kann Kunden für POS-Aufträge suchen und auswählen."
},
"view_customer_details": {
"label": "Kundendetails anzeigen",
"description": "Kann Kundendetails anhand einer Kundennummer laden."
},
"view_customer_notes": {
"label": "Kundennotizen anzeigen",
"description": "Kann Kundennotizen im POS lesen."
},
"add_customer_notes": {
"label": "Kundennotizen hinzufügen",
"description": "Kann Kundennotizen im POS hinzufügen."
},
"view_customer_flags": {
"label": "Kundenmarkierungen anzeigen",
"description": "Kann Kundenmarkierungen sehen, die Auftragsanforderungen und Produktregeln beeinflussen."
},
"search_vehicles": {
"label": "Fahrzeuge suchen",
"description": "Kann Kennzeichen suchen und den Fahrzeugstatus sehen."
},
"view_vehicle_matches": {
"label": "Fahrzeugtreffer anzeigen",
"description": "Kann Kundentreffer für Fahrzeuge und Vorschläge zu unbekannten Fahrzeugen sehen."
},
"view_vehicle_history": {
"label": "Fahrzeughistorie anzeigen",
"description": "Kann die letzte Auftragshistorie für ein Kennzeichen sehen."
},
"view_order_attachments": {
"label": "Auftragsanhänge anzeigen",
"description": "Kann Anhänge auf Aufträgen auflisten."
},
"add_order_attachments": {
"label": "Auftragsanhänge hinzufügen",
"description": "Kann Dateien hochladen und Waschzertifikate an Aufträge anhängen."
},
"download_order_attachments": {
"label": "Auftragsanhänge herunterladen",
"description": "Kann Auftragsanhänge öffnen und herunterladen."
},
"view_plate_scans": {
"label": "Kennzeichenscans anzeigen",
"description": "Kann aktuelle Kennzeichenscans und Scanner für zugewiesene Abteilungen sehen."
},
"view_department_bookings": {
"label": "Abteilungsbuchungen anzeigen",
"description": "Kann Buchungen für zugewiesene Abteilungen sehen."
@@ -91,6 +91,22 @@
"subtitle": "Role permissions",
"title": "Role {id} permissions",
"title_with_name": "{name} permissions"
},
"templates": {
"apply": "Apply {template} template",
"confirm_button": "Apply template",
"confirm_text": "Add {count} missing permissions from {template} to {role}?",
"confirm_title": "Apply permission template?",
"error_text": "One or more permissions from {template} could not be added to {role}. The role list was reloaded.",
"error_title": "Could not apply template",
"load_error": "Could not load templates. Try again",
"loading": "Loading templates...",
"section": "Limited backoffice templates",
"success_text": "Added {count} permissions from {template} to {role}.",
"success_title": "Template applied",
"unavailable": "No templates are available.",
"up_to_date_text": "{role} already has every permission in {template}.",
"up_to_date_title": "Role is up to date"
}
}
}
@@ -78,6 +78,7 @@
},
"employees": {
"create": "@.capitalize:{'terms.glossary.create'} @:{'terms.glossary.new'} @:{'terms.glossary.employee'}",
"migrate_to_limited_backoffice": "Migrate to limited backoffice",
"subtitle": "@.capitalize:{'terms.glossary.here'} @:{'terms.glossary.you'} @:{'terms.glossary.can'} @:{'terms.glossary.see'} @:{'terms.glossary.a'} @:{'terms.glossary.list'} @:{'terms.glossary.of'} @:{'terms.glossary.all'} @:{'terms.glossary.employees'} @:{'terms.glossary.in'} @:{'terms.replication.article.host_mention'} @:{'terms.glossary.system'}"
},
"orders": {
+143 -13
View File
@@ -28,16 +28,16 @@
"title": "@:{'phrases.compat.limited_backoffice.forbidden.title'}",
"department": "@:{'phrases.compat.limited_backoffice.forbidden.department'}"
},
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"setup_required_title": "@:{'phrases.compat.limited_backoffice.prices.setup_required_title'}",
"setup_required_message": "@:{'phrases.compat.limited_backoffice.prices.setup_required_message'}",
"no_products": "@:{'phrases.compat.limited_backoffice.prices.no_products'}"
@@ -126,6 +126,11 @@
"groups": {
"account": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -177,6 +182,66 @@
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -338,12 +403,12 @@
},
"roles": {
"viewer": {
"label": "Viewer",
"description": "@.capitalize:{'terms.glossary.can'} sign @:{'terms.glossary.in'} @:{'terms.glossary.and'} view @:{'terms.glossary.assigned'} @:{'terms.glossary.department'} data."
"label": "Deactivated",
"description": "Keeps the employee registered without order, booking, or management permissions."
},
"cashier": {
"label": "Cashier",
"description": "@.capitalize:{'terms.glossary.can'} work with @:{'terms.glossary.orders'} @:{'terms.glossary.and'} order lines @:{'terms.glossary.for'} @:{'terms.glossary.assigned'} @:{'terms.glossary.departments'}."
"description": "@.capitalize:{'terms.glossary.can'} work with @:{'terms.glossary.orders'}, order lines @:{'terms.glossary.and'} @:{'terms.glossary.bookings'} @:{'terms.glossary.for'} @:{'terms.glossary.assigned'} @:{'terms.glossary.departments'}."
},
"booking_coordinator": {
"label": "Booking coordinator",
@@ -378,6 +443,11 @@
"groups": {
"account": "Account",
"orders": "Orders",
"products": "Products",
"customers": "Customers",
"vehicles": "Vehicles",
"attachments": "Attachments",
"scanner": "Scanners",
"bookings": "Bookings",
"time_bookings": "Time bookings",
"reports": "Reports",
@@ -429,6 +499,66 @@
"label": "Charge orders",
"description": "Can take payment or charge a payment intent for an order."
},
"complete_orders": {
"label": "Complete orders",
"description": "Can mark orders as completed."
},
"view_product_catalog": {
"label": "View product catalog",
"description": "Can load POS categories, products, prices, and addons."
},
"view_product_recommendations": {
"label": "View product recommendations",
"description": "Can see product suggestions based on orders and vehicle data."
},
"search_customers": {
"label": "Search customers",
"description": "Can search and select customers for POS orders."
},
"view_customer_details": {
"label": "View customer details",
"description": "Can load customer details from a customer number."
},
"view_customer_notes": {
"label": "View customer notes",
"description": "Can read customer notes in POS."
},
"add_customer_notes": {
"label": "Add customer notes",
"description": "Can add customer notes from POS."
},
"view_customer_flags": {
"label": "View customer flags",
"description": "Can see customer flags that affect order requirements and product rules."
},
"search_vehicles": {
"label": "Search vehicles",
"description": "Can search license plates and see vehicle status."
},
"view_vehicle_matches": {
"label": "View vehicle matches",
"description": "Can see vehicle customer matches and unknown vehicle suggestions."
},
"view_vehicle_history": {
"label": "View vehicle history",
"description": "Can see recent order history for a license plate."
},
"view_order_attachments": {
"label": "View order attachments",
"description": "Can list attachments on orders."
},
"add_order_attachments": {
"label": "Add order attachments",
"description": "Can upload files and attach wash certificates to orders."
},
"download_order_attachments": {
"label": "Download order attachments",
"description": "Can open and download order attachments."
},
"view_plate_scans": {
"label": "View plate scans",
"description": "Can view recent license plate scans and scanners for assigned departments."
},
"view_department_bookings": {
"label": "View department bookings",
"description": "Can see bookings for assigned departments."
@@ -91,6 +91,22 @@
"title": "@:{'phrases.compat.roles.permissions.title'}",
"title_with_name": "@:{'phrases.compat.roles.permissions.title_with_name'}"
},
"templates": {
"apply": "@:{'phrases.compat.roles.templates.apply'}",
"confirm_button": "@:{'phrases.compat.roles.templates.confirm_button'}",
"confirm_text": "@:{'phrases.compat.roles.templates.confirm_text'}",
"confirm_title": "@:{'phrases.compat.roles.templates.confirm_title'}",
"error_text": "@:{'phrases.compat.roles.templates.error_text'}",
"error_title": "@:{'phrases.compat.roles.templates.error_title'}",
"load_error": "@:{'phrases.compat.roles.templates.load_error'}",
"loading": "@:{'phrases.compat.roles.templates.loading'}",
"section": "@:{'phrases.compat.roles.templates.section'}",
"success_text": "@:{'phrases.compat.roles.templates.success_text'}",
"success_title": "@:{'phrases.compat.roles.templates.success_title'}",
"unavailable": "@:{'phrases.compat.roles.templates.unavailable'}",
"up_to_date_text": "@:{'phrases.compat.roles.templates.up_to_date_text'}",
"up_to_date_title": "@:{'phrases.compat.roles.templates.up_to_date_title'}"
},
"subtitle": "@:{'phrases.compat.roles.subtitle'}",
"title": "@:{'phrases.compat.common.roles'}"
}
@@ -91,6 +91,22 @@
"subtitle": "Rolletillatelser",
"title": "Tillatelser for rolle {id}",
"title_with_name": "Tillatelser for {name}"
},
"templates": {
"apply": "Bruk {template}-mal",
"confirm_button": "Bruk mal",
"confirm_text": "Legg til {count} manglende tillatelser fra {template} til {role}?",
"confirm_title": "Bruke tillatelsesmal?",
"error_text": "En eller flere tillatelser fra {template} kunne ikke legges til i {role}. Rollelisten ble lastet inn pa nytt.",
"error_title": "Kunne ikke bruke mal",
"load_error": "Kunne ikke laste maler. Prov igjen",
"loading": "Laster maler...",
"section": "Begrenset backoffice-maler",
"success_text": "La til {count} tillatelser fra {template} i {role}.",
"success_title": "Mal brukt",
"unavailable": "Ingen maler er tilgjengelige.",
"up_to_date_text": "{role} har allerede alle tillatelser i {template}.",
"up_to_date_title": "Rollen er oppdatert"
}
}
}
@@ -78,6 +78,7 @@
},
"employees": {
"create": "@:{'terms.glossary.opprett'} @:{'terms.glossary.ny'} medarbeider",
"migrate_to_limited_backoffice": "Migrer til begrenset backoffice",
"subtitle": "@.capitalize:{'terms.glossary.her'} @:{'terms.glossary.kan'} @:{'terms.glossary.du'} @:{'terms.glossary.se'} @:{'terms.replication.host_definite_suffix'} @:{'terms.glossary.liste'} @:{'terms.glossary.over'} @:{'terms.glossary.alle'} @:{'terms.glossary.ansatte'} @:{'terms.glossary.i'} @:{'terms.glossary.systemet'}"
},
"orders": {
+143 -13
View File
@@ -28,16 +28,16 @@
"title": "@:{'phrases.compat.limited_backoffice.forbidden.title'}",
"department": "@:{'phrases.compat.limited_backoffice.forbidden.department'}"
},
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"setup_required_title": "@:{'phrases.compat.limited_backoffice.prices.setup_required_title'}",
"setup_required_message": "@:{'phrases.compat.limited_backoffice.prices.setup_required_message'}",
"no_products": "@:{'phrases.compat.limited_backoffice.prices.no_products'}"
@@ -126,6 +126,11 @@
"groups": {
"account": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -177,6 +182,66 @@
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -338,12 +403,12 @@
},
"roles": {
"viewer": {
"label": "Viser",
"description": "@.capitalize:{'terms.glossary.kan'} logge inn @:{'terms.glossary.og'} se data @:{'terms.glossary.for'} @:{'terms.glossary.tildelte'} @:{'terms.glossary.avdelinger'}."
"label": "Deaktivert",
"description": "Holder den ansatte registrert uten tilgang til ordre-, booking- eller administrasjonsfunksjoner."
},
"cashier": {
"label": "Kasserer",
"description": "@.capitalize:{'terms.glossary.kan'} arbeide med @:{'terms.glossary.ordre'} @:{'terms.glossary.og'} ordrelinjer @:{'terms.glossary.for'} @:{'terms.glossary.tildelte'} @:{'terms.glossary.avdelinger'}."
"description": "@.capitalize:{'terms.glossary.kan'} arbeide med @:{'terms.glossary.ordre'}, ordrelinjer @:{'terms.glossary.og'} @:{'terms.glossary.bookinger'} @:{'terms.glossary.for'} @:{'terms.glossary.tildelte'} @:{'terms.glossary.avdelinger'}."
},
"booking_coordinator": {
"label": "Bookingkoordinator",
@@ -378,6 +443,11 @@
"groups": {
"account": "Konto",
"orders": "Ordrer",
"products": "Produkter",
"customers": "Kunder",
"vehicles": "Kjøretøy",
"attachments": "Vedlegg",
"scanner": "Skannere",
"bookings": "Bookinger",
"time_bookings": "Tidsbookinger",
"reports": "Rapporter",
@@ -429,6 +499,66 @@
"label": "Belast ordrer",
"description": "Kan ta betaling eller belaste en betalingsreservasjon for en ordre."
},
"complete_orders": {
"label": "Fullfør ordrer",
"description": "Kan markere ordrer som fullført."
},
"view_product_catalog": {
"label": "Se produktkatalog",
"description": "Kan laste POS-kategorier, produkter, priser og tillegg."
},
"view_product_recommendations": {
"label": "Se produktforslag",
"description": "Kan se produktforslag basert på ordrer og kjøretøydata."
},
"search_customers": {
"label": "Søk kunder",
"description": "Kan søke og velge kunder for POS-ordrer."
},
"view_customer_details": {
"label": "Se kundeopplysninger",
"description": "Kan laste kundeopplysninger fra et kundenummer."
},
"view_customer_notes": {
"label": "Se kundemerknader",
"description": "Kan lese kundemerknader i POS."
},
"add_customer_notes": {
"label": "Legg til kundemerknader",
"description": "Kan legge til kundemerknader fra POS."
},
"view_customer_flags": {
"label": "Se kundemarkeringer",
"description": "Kan se kundemarkeringer som påvirker ordrekrav og produktregler."
},
"search_vehicles": {
"label": "Søk kjøretøy",
"description": "Kan søke etter registreringsnummer og se kjøretøystatus."
},
"view_vehicle_matches": {
"label": "Se kjøretøytreff",
"description": "Kan se kundetreff for kjøretøy og forslag til ukjente kjøretøy."
},
"view_vehicle_history": {
"label": "Se kjøretøyhistorikk",
"description": "Kan se nylig ordrehistorikk for et registreringsnummer."
},
"view_order_attachments": {
"label": "Se ordrevedlegg",
"description": "Kan liste vedlegg på ordrer."
},
"add_order_attachments": {
"label": "Legg til ordrevedlegg",
"description": "Kan laste opp filer og legge ved vaskesertifikater på ordrer."
},
"download_order_attachments": {
"label": "Last ned ordrevedlegg",
"description": "Kan åpne og laste ned ordrevedlegg."
},
"view_plate_scans": {
"label": "Se nummerskiltskanninger",
"description": "Kan se nylige nummerskiltskanninger og skannere for tildelte avdelinger."
},
"view_department_bookings": {
"label": "Se avdelingsbookinger",
"description": "Kan se bookinger for tildelte avdelinger."
@@ -91,6 +91,22 @@
"subtitle": "Rollbehorigheter",
"title": "Behorigheter for roll {id}",
"title_with_name": "Behorigheter for {name}"
},
"templates": {
"apply": "Anvand mallen {template}",
"confirm_button": "Anvand mall",
"confirm_text": "Lagg till {count} saknade behorigheter fran {template} till {role}?",
"confirm_title": "Anvanda behorighetsmall?",
"error_text": "En eller flera behorigheter fran {template} kunde inte laggas till i {role}. Rolllistan laddades om.",
"error_title": "Kunde inte anvanda mall",
"load_error": "Kunde inte ladda mallar. Forsok igen",
"loading": "Laddar mallar...",
"section": "Begransade backoffice-mallar",
"success_text": "Lade till {count} behorigheter fran {template} i {role}.",
"success_title": "Mall anvand",
"unavailable": "Inga mallar ar tillgangliga.",
"up_to_date_text": "{role} har redan alla behorigheter i {template}.",
"up_to_date_title": "Rollen ar uppdaterad"
}
}
}
@@ -78,6 +78,7 @@
},
"employees": {
"create": "@.capitalize:{'terms.glossary.skapa'} @:{'terms.glossary.ny'} @:{'terms.glossary.anstalld'}",
"migrate_to_limited_backoffice": "Migrera till begränsad backoffice",
"subtitle": "@.capitalize:{'terms.glossary.har_2'} @:{'terms.glossary.kan'} @:{'terms.glossary.du'} @:{'terms.glossary.se'} @:{'terms.replication.host_definite_suffix'} @:{'terms.glossary.lista'} @:{'terms.glossary.over'} @:{'terms.glossary.alla'} @:{'terms.glossary.anstallda'} @:{'terms.glossary.i'} @:{'terms.glossary.systemet'}"
},
"orders": {
+143 -13
View File
@@ -28,16 +28,16 @@
"title": "@:{'phrases.compat.limited_backoffice.forbidden.title'}",
"department": "@:{'phrases.compat.limited_backoffice.forbidden.department'}"
},
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"prices": {
"title": "@:{'phrases.compat.limited_backoffice.prices.title'}",
"save": "@:{'phrases.compat.limited_backoffice.prices.save'}",
"saved": "@:{'phrases.compat.limited_backoffice.prices.saved'}",
"autosave_saving": "@:{'phrases.compat.limited_backoffice.prices.autosave_saving'}",
"autosave_pending": "@:{'phrases.compat.limited_backoffice.prices.autosave_pending'}",
"autosave_saved": "@:{'phrases.compat.limited_backoffice.prices.autosave_saved'}",
"product": "@:{'phrases.compat.limited_backoffice.prices.product'}",
"price": "@:{'phrases.compat.limited_backoffice.prices.price'}",
"price_required": "@:{'phrases.compat.limited_backoffice.prices.price_required'}",
"setup_required_title": "@:{'phrases.compat.limited_backoffice.prices.setup_required_title'}",
"setup_required_message": "@:{'phrases.compat.limited_backoffice.prices.setup_required_message'}",
"no_products": "@:{'phrases.compat.limited_backoffice.prices.no_products'}"
@@ -126,6 +126,11 @@
"groups": {
"account": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.account'}",
"orders": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.orders'}",
"products": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.products'}",
"customers": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.customers'}",
"vehicles": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.vehicles'}",
"attachments": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.attachments'}",
"scanner": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.scanner'}",
"bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.bookings'}",
"time_bookings": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.time_bookings'}",
"reports": "@:{'phrases.compat.limited_backoffice.role_permissions.groups.reports'}",
@@ -177,6 +182,66 @@
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.charge_orders.description'}"
},
"complete_orders": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.complete_orders.description'}"
},
"view_product_catalog": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_catalog.description'}"
},
"view_product_recommendations": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description'}"
},
"search_customers": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_customers.description'}"
},
"view_customer_details": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_details.description'}"
},
"view_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_notes.description'}"
},
"add_customer_notes": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_customer_notes.description'}"
},
"view_customer_flags": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_customer_flags.description'}"
},
"search_vehicles": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.search_vehicles.description'}"
},
"view_vehicle_matches": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description'}"
},
"view_vehicle_history": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description'}"
},
"view_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_order_attachments.description'}"
},
"add_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.add_order_attachments.description'}"
},
"download_order_attachments": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.download_order_attachments.description'}"
},
"view_plate_scans": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_plate_scans.description'}"
},
"view_department_bookings": {
"label": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.label'}",
"description": "@:{'phrases.compat.limited_backoffice.role_permissions.capabilities.view_department_bookings.description'}"
@@ -338,12 +403,12 @@
},
"roles": {
"viewer": {
"label": "Visare",
"description": "@.capitalize:{'terms.glossary.kan'} logga in @:{'terms.glossary.och'} se data @:{'terms.glossary.for'} @:{'terms.glossary.tilldelade'} @:{'terms.glossary.avdelningar'}."
"label": "Inaktiverad",
"description": "Behåller medarbetaren registrerad utan åtkomst till order-, boknings- eller administrationsfunktioner."
},
"cashier": {
"label": "Kassör",
"description": "@.capitalize:{'terms.glossary.kan'} arbeta med @:{'terms.glossary.order'} @:{'terms.glossary.och'} orderrader @:{'terms.glossary.for'} @:{'terms.glossary.tilldelade'} @:{'terms.glossary.avdelningar'}."
"description": "@.capitalize:{'terms.glossary.kan'} arbeta med @:{'terms.glossary.order'}, orderrader @:{'terms.glossary.och'} @:{'terms.glossary.bokningar'} @:{'terms.glossary.for'} @:{'terms.glossary.tilldelade'} @:{'terms.glossary.avdelningar'}."
},
"booking_coordinator": {
"label": "Bokningskoordinator",
@@ -378,6 +443,11 @@
"groups": {
"account": "Konto",
"orders": "Order",
"products": "Produkter",
"customers": "Kunder",
"vehicles": "Fordon",
"attachments": "Bilagor",
"scanner": "Skannrar",
"bookings": "Bokningar",
"time_bookings": "Tidsbokningar",
"reports": "Rapporter",
@@ -429,6 +499,66 @@
"label": "Debitera order",
"description": "Kan ta betalt eller debitera en betalningsreservation för en order."
},
"complete_orders": {
"label": "Slutför ordrar",
"description": "Kan markera ordrar som slutförda."
},
"view_product_catalog": {
"label": "Visa produktkatalog",
"description": "Kan läsa in POS-kategorier, produkter, priser och tillval."
},
"view_product_recommendations": {
"label": "Visa produktförslag",
"description": "Kan se produktförslag baserade på ordrar och fordonsdata."
},
"search_customers": {
"label": "Sök kunder",
"description": "Kan söka och välja kunder för POS-ordrar."
},
"view_customer_details": {
"label": "Visa kunduppgifter",
"description": "Kan läsa in kunduppgifter från ett kundnummer."
},
"view_customer_notes": {
"label": "Visa kundanteckningar",
"description": "Kan läsa kundanteckningar i POS."
},
"add_customer_notes": {
"label": "Lägg till kundanteckningar",
"description": "Kan lägga till kundanteckningar från POS."
},
"view_customer_flags": {
"label": "Visa kundmarkeringar",
"description": "Kan se kundmarkeringar som påverkar orderkrav och produktregler."
},
"search_vehicles": {
"label": "Sök fordon",
"description": "Kan söka registreringsnummer och se fordonsstatus."
},
"view_vehicle_matches": {
"label": "Visa fordonsträffar",
"description": "Kan se kundträffar för fordon och förslag på okända fordon."
},
"view_vehicle_history": {
"label": "Visa fordonshistorik",
"description": "Kan se senaste orderhistorik för ett registreringsnummer."
},
"view_order_attachments": {
"label": "Visa orderbilagor",
"description": "Kan lista bilagor på ordrar."
},
"add_order_attachments": {
"label": "Lägg till orderbilagor",
"description": "Kan ladda upp filer och bifoga tvättcertifikat till ordrar."
},
"download_order_attachments": {
"label": "Ladda ner orderbilagor",
"description": "Kan öppna och ladda ner orderbilagor."
},
"view_plate_scans": {
"label": "Visa nummerskyltsavläsningar",
"description": "Kan se senaste nummerskyltsavläsningar och skannrar för tilldelade avdelningar."
},
"view_department_bookings": {
"label": "Se avdelningsbokningar",
"description": "Kan se bokningar för tilldelade avdelningar."
+5 -6
View File
@@ -18,8 +18,10 @@ export const getLimitedBackofficeRoles = () => limitedBackofficeRequest("/roles"
export const getLimitedBackofficeEmployees = ({ includeInactive = false } = {}) =>
limitedBackofficeRequest("/employees", "GET", { include_inactive: includeInactive ? "true" : "false" });
export const createLimitedBackofficeEmployee = (payload) =>
limitedBackofficeRequest("/employees", "POST", payload);
export const createLimitedBackofficeEmployee = (payload) => limitedBackofficeRequest("/employees", "POST", payload);
export const migrateLimitedBackofficeEmployee = (employeeId, payload) =>
limitedBackofficeRequest(`/employees/${encodeURIComponent(String(employeeId))}/migrate`, "POST", payload);
export const updateLimitedBackofficeEmployee = (employeeId, payload) =>
limitedBackofficeRequest(`/employees/${encodeURIComponent(String(employeeId))}`, "PUT", payload);
@@ -33,7 +35,4 @@ export const deactivateLimitedBackofficeEmployee = (employeeId) =>
export const unwrapLimitedBackofficeResponse = (response) => response?.data?.data ?? response?.data ?? null;
export const limitedBackofficeErrorMessage = (error, fallback) =>
error?.response?.data?.data?.message ||
error?.response?.data?.message ||
error?.message ||
fallback;
error?.response?.data?.data?.message || error?.response?.data?.message || error?.message || fallback;
@@ -74,8 +74,8 @@ const selectedDepartmentId = computed(() => {
return Number.isInteger(departmentId) && departmentId > 0 ? departmentId : null;
});
const selectedDepartment = computed(() =>
departments.value.find((department) => Number(department.id) === selectedDepartmentId.value) || null
const selectedDepartment = computed(
() => departments.value.find((department) => Number(department.id) === selectedDepartmentId.value) || null
);
const hasForbiddenDepartment = computed(
@@ -112,6 +112,21 @@ const rolePermissionGroupMessages = computed(() => ({
orders: {
label: t("templates.limited_backoffice.role_permissions.groups.orders"),
},
products: {
label: t("templates.limited_backoffice.role_permissions.groups.products"),
},
customers: {
label: t("templates.limited_backoffice.role_permissions.groups.customers"),
},
vehicles: {
label: t("templates.limited_backoffice.role_permissions.groups.vehicles"),
},
attachments: {
label: t("templates.limited_backoffice.role_permissions.groups.attachments"),
},
scanner: {
label: t("templates.limited_backoffice.role_permissions.groups.scanner"),
},
bookings: {
label: t("templates.limited_backoffice.role_permissions.groups.bookings"),
},
@@ -154,6 +169,10 @@ const roleCapabilityMessages = computed(() => ({
label: t("templates.limited_backoffice.role_permissions.capabilities.delete_orders.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.delete_orders.description"),
},
complete_orders: {
label: t("templates.limited_backoffice.role_permissions.capabilities.complete_orders.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.complete_orders.description"),
},
view_order_items: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_order_items.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_order_items.description"),
@@ -174,6 +193,64 @@ const roleCapabilityMessages = computed(() => ({
label: t("templates.limited_backoffice.role_permissions.capabilities.charge_orders.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.charge_orders.description"),
},
view_product_catalog: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_product_catalog.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_product_catalog.description"),
},
view_product_recommendations: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_product_recommendations.label"),
description: t(
"templates.limited_backoffice.role_permissions.capabilities.view_product_recommendations.description"
),
},
search_customers: {
label: t("templates.limited_backoffice.role_permissions.capabilities.search_customers.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.search_customers.description"),
},
view_customer_details: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_customer_details.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_customer_details.description"),
},
view_customer_notes: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_customer_notes.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_customer_notes.description"),
},
add_customer_notes: {
label: t("templates.limited_backoffice.role_permissions.capabilities.add_customer_notes.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.add_customer_notes.description"),
},
view_customer_flags: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_customer_flags.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_customer_flags.description"),
},
search_vehicles: {
label: t("templates.limited_backoffice.role_permissions.capabilities.search_vehicles.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.search_vehicles.description"),
},
view_vehicle_matches: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_vehicle_matches.description"),
},
view_vehicle_history: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_vehicle_history.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_vehicle_history.description"),
},
view_order_attachments: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_order_attachments.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_order_attachments.description"),
},
add_order_attachments: {
label: t("templates.limited_backoffice.role_permissions.capabilities.add_order_attachments.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.add_order_attachments.description"),
},
download_order_attachments: {
label: t("templates.limited_backoffice.role_permissions.capabilities.download_order_attachments.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.download_order_attachments.description"),
},
view_plate_scans: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_plate_scans.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_plate_scans.description"),
},
view_department_bookings: {
label: t("templates.limited_backoffice.role_permissions.capabilities.view_department_bookings.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.view_department_bookings.description"),
@@ -204,7 +281,9 @@ const roleCapabilityMessages = computed(() => ({
},
create_time_booking_entries: {
label: t("templates.limited_backoffice.role_permissions.capabilities.create_time_booking_entries.label"),
description: t("templates.limited_backoffice.role_permissions.capabilities.create_time_booking_entries.description"),
description: t(
"templates.limited_backoffice.role_permissions.capabilities.create_time_booking_entries.description"
),
},
edit_time_booking_entries: {
label: t("templates.limited_backoffice.role_permissions.capabilities.edit_time_booking_entries.label"),
@@ -339,10 +418,7 @@ const loadData = async () => {
await loadEmployees();
} catch (error) {
errorMessage.value = limitedBackofficeErrorMessage(
error,
t("templates.limited_backoffice.errors.load_employees")
);
errorMessage.value = limitedBackofficeErrorMessage(error, t("templates.limited_backoffice.errors.load_employees"));
} finally {
loading.value = false;
}
@@ -428,10 +504,7 @@ const saveEmployee = async () => {
resetForm();
await loadEmployees();
} catch (error) {
errorMessage.value = limitedBackofficeErrorMessage(
error,
t("templates.limited_backoffice.errors.save_employee")
);
errorMessage.value = limitedBackofficeErrorMessage(error, t("templates.limited_backoffice.errors.save_employee"));
} finally {
saving.value = false;
}
@@ -540,10 +613,7 @@ const reloadEmployees = async () => {
try {
await loadEmployees();
} catch (error) {
errorMessage.value = limitedBackofficeErrorMessage(
error,
t("templates.limited_backoffice.errors.load_employees")
);
errorMessage.value = limitedBackofficeErrorMessage(error, t("templates.limited_backoffice.errors.load_employees"));
} finally {
loading.value = false;
}
@@ -576,7 +646,11 @@ watch(
show-department-switcher
@change-department="changeDepartment"
>
<div v-if="hasForbiddenDepartment" class="notification is-danger is-light" data-testid="limited-employees-forbidden">
<div
v-if="hasForbiddenDepartment"
class="notification is-danger is-light"
data-testid="limited-employees-forbidden"
>
<strong>{{ t("templates.limited_backoffice.forbidden.title") }}</strong>
<p>{{ t("templates.limited_backoffice.forbidden.department") }}</p>
</div>
@@ -746,7 +820,11 @@ watch(
</p>
</div>
<div v-if="formAttempted && !isFormValid" class="notification is-danger is-light" data-testid="limited-employee-validation">
<div
v-if="formAttempted && !isFormValid"
class="notification is-danger is-light"
data-testid="limited-employee-validation"
>
{{ t("templates.limited_backoffice.employees.validation") }}
</div>
@@ -814,7 +892,10 @@ watch(
</div>
<div v-if="!loading && visibleEmployees.length > 0" class="table-container">
<table class="table is-fullwidth is-hoverable limited-employees-table" data-testid="limited-employees-table">
<table
class="table is-fullwidth is-hoverable limited-employees-table"
data-testid="limited-employees-table"
>
<thead>
<tr>
<th>{{ t("templates.limited_backoffice.employees.user_id") }}</th>
@@ -822,11 +903,17 @@ watch(
<th>{{ t("templates.limited_backoffice.employees.role") }}</th>
<th>{{ t("templates.limited_backoffice.employees.departments") }}</th>
<th>{{ t("templates.limited_backoffice.employees.status") }}</th>
<th class="limited-employees-table__actions">{{ t("templates.limited_backoffice.employees.actions") }}</th>
<th class="limited-employees-table__actions">
{{ t("templates.limited_backoffice.employees.actions") }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="employee in visibleEmployees" :key="employee.id" :data-testid="`limited-employee-row-${employee.id}`">
<tr
v-for="employee in visibleEmployees"
:key="employee.id"
:data-testid="`limited-employee-row-${employee.id}`"
>
<td>
<span class="tag is-light" :data-testid="`limited-employee-user-id-${employee.id}`">
{{ employee.user_id || employee.id }}
@@ -848,7 +935,11 @@ watch(
<p class="has-text-grey is-size-7">{{ roleDescription(employee.role) }}</p>
</td>
<td>
<span v-for="department in employee.departments" :key="department.id" class="tag is-light mr-1 mb-1">
<span
v-for="department in employee.departments"
:key="department.id"
class="tag is-light mr-1 mb-1"
>
{{ department.name }}
</span>
</td>
+6
View File
@@ -350,6 +350,10 @@ async function readStoredToken(page: Page) {
}
}
async function waitForAppRootMounted(page: Page) {
await expect.poll(async () => page.locator("#app > *").count(), { timeout: AUTH_TIMEOUT }).toBeGreaterThan(0);
}
async function settleAuthenticatedNavigation(page: Page, targetPath: string, targetUrl: RegExp) {
await expect.poll(() => readStoredToken(page), { timeout: AUTH_TIMEOUT }).not.toBeNull();
const navigateToTarget = async () => {
@@ -376,6 +380,8 @@ async function settleAuthenticatedNavigation(page: Page, targetPath: string, tar
await navigateToTarget();
await expect.poll(() => page.url(), { timeout: AUTH_TIMEOUT }).toMatch(targetUrl);
}
await waitForAppRootMounted(page);
}
/**
+16
View File
@@ -1112,6 +1112,7 @@ test.describe("Invoicing period tab", () => {
const usageOrderRequests = [];
const fastLinkRequests = [];
const automationAcceptRequests = [];
const importUsageRequests = [];
let automation = {
id: 7101,
status: "suggested",
@@ -1133,6 +1134,15 @@ test.describe("Invoicing period tab", () => {
await openPeriodView(page);
await page.route("**/modules/xlvask/tasks/import-usage**", async (route) => {
const url = new URL(route.request().url());
importUsageRequests.push({
dateFrom: url.searchParams.get("dateFrom"),
dateTo: url.searchParams.get("dateTo"),
});
await route.fulfill(json({ data: "Usage logs imported" }));
});
await page.route("**/modules/xlvask/services/usage/orders**", async (route) => {
const path = new URL(route.request().url()).pathname;
if (
@@ -1285,6 +1295,12 @@ test.describe("Invoicing period tab", () => {
request.filters.includes("StartTime-date_to:2026-03-31")
)
).toBe(true);
await selfWashView.getByRole("button", { name: /import/i }).click();
await expect.poll(() => importUsageRequests.length).toBe(1);
expect(importUsageRequests[0]).toEqual({
dateFrom: "2026-03-01",
dateTo: "2026-03-31",
});
});
test("@smoke period view shows flags and saves automatic flag decisions", async ({ page }) => {
+120 -4
View File
@@ -148,6 +148,7 @@ const rolePermissionGroups = {
"view_orders",
"create_orders",
"edit_orders",
"complete_orders",
"view_order_items",
"create_order_items",
"update_order_lines",
@@ -155,6 +156,43 @@ const rolePermissionGroups = {
"charge_orders",
],
},
{
key: "products",
capabilities: ["view_product_catalog", "view_product_recommendations"],
},
{
key: "customers",
capabilities: [
"search_customers",
"view_customer_details",
"view_customer_notes",
"add_customer_notes",
"view_customer_flags",
],
},
{
key: "vehicles",
capabilities: ["search_vehicles", "view_vehicle_matches", "view_vehicle_history"],
},
{
key: "attachments",
capabilities: ["view_order_attachments", "add_order_attachments", "download_order_attachments"],
},
{
key: "scanner",
capabilities: ["view_plate_scans"],
},
{
key: "bookings",
capabilities: [
"view_department_bookings",
"view_own_bookings",
"update_bookings",
"create_bookings",
"mark_bookings_complete",
"send_booking_confirmations",
],
},
],
booking_coordinator: [
{ key: "account", capabilities: ["sign_in", "view_own_permissions"] },
@@ -184,6 +222,7 @@ const rolePermissionGroups = {
"create_orders",
"edit_orders",
"delete_orders",
"complete_orders",
"view_order_items",
"create_order_items",
"update_order_lines",
@@ -191,6 +230,32 @@ const rolePermissionGroups = {
"charge_orders",
],
},
{
key: "products",
capabilities: ["view_product_catalog", "view_product_recommendations"],
},
{
key: "customers",
capabilities: [
"search_customers",
"view_customer_details",
"view_customer_notes",
"add_customer_notes",
"view_customer_flags",
],
},
{
key: "vehicles",
capabilities: ["search_vehicles", "view_vehicle_matches", "view_vehicle_history"],
},
{
key: "attachments",
capabilities: ["view_order_attachments", "add_order_attachments", "download_order_attachments"],
},
{
key: "scanner",
capabilities: ["view_plate_scans"],
},
{
key: "bookings",
capabilities: [
@@ -213,6 +278,7 @@ const rolePermissionGroups = {
"create_orders",
"edit_orders",
"delete_orders",
"complete_orders",
"view_order_items",
"create_order_items",
"update_order_lines",
@@ -220,6 +286,32 @@ const rolePermissionGroups = {
"charge_orders",
],
},
{
key: "products",
capabilities: ["view_product_catalog", "view_product_recommendations"],
},
{
key: "customers",
capabilities: [
"search_customers",
"view_customer_details",
"view_customer_notes",
"add_customer_notes",
"view_customer_flags",
],
},
{
key: "vehicles",
capabilities: ["search_vehicles", "view_vehicle_matches", "view_vehicle_history"],
},
{
key: "attachments",
capabilities: ["view_order_attachments", "add_order_attachments", "download_order_attachments"],
},
{
key: "scanner",
capabilities: ["view_plate_scans"],
},
{
key: "bookings",
capabilities: [
@@ -245,7 +337,12 @@ const remotePricePayload = {
};
const rolesPayload = [
{ key: "viewer", label: "Viewer", description: "Can view.", permission_groups: rolePermissionGroups.viewer },
{
key: "viewer",
label: "Deactivated",
description: "No order, booking, or management access.",
permission_groups: rolePermissionGroups.viewer,
},
{ key: "cashier", label: "Cashier", description: "Can sell.", permission_groups: rolePermissionGroups.cashier },
{
key: "booking_coordinator",
@@ -272,7 +369,7 @@ const employeesPayload = [
{
id: 501,
user_id: 501,
customer_number: 900000501,
customer_number: 0,
display_name: "Casey Clerk",
email: "casey@example.com",
phone_country_code: 45,
@@ -285,11 +382,11 @@ const employeesPayload = [
},
{
id: 502,
customer_number: 900000502,
customer_number: 0,
display_name: "Riley Remote",
email: "riley@example.com",
active: true,
role: { key: "viewer", label: "Viewer", description: "Can view." },
role: { key: "viewer", label: "Deactivated", description: "No order, booking, or management access." },
departments: [{ id: 2, name: "Remote Depot" }],
created_at: "2026-01-01 00:00:00",
updated_at: "2026-01-01 00:00:00",
@@ -842,17 +939,36 @@ test.describe("Limited backoffice", () => {
await expect(modal).toBeVisible();
await expect(modal).toContainText("Role permissions");
await expect(modal).toContainText("Every capability is limited to the departments selected for the employee.");
await expect(page.getByTestId("limited-role-permissions-role-viewer")).toContainText("Deactivated");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Cashier");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Orders");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Products");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Customers");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Vehicles");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Attachments");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Scanners");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Bookings");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("View orders");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Complete orders");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("View product catalog");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Search customers");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Search vehicles");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Add order attachments");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("View plate scans");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Create bookings");
await expect(page.getByTestId("limited-role-permissions-role-cashier")).toContainText("Create order lines");
await expect(page.getByTestId("limited-role-permissions-role-viewer")).toContainText("Selected");
for (const rawPermission of [
"list_orders",
"add_order",
"fetch_order",
"edit_order_items",
"delete_order_items",
"search_customers",
"list_order_attachments",
"list_products",
"add_bookings",
"department_timebookings_entries_get",
"limited_backoffice_employees_manage",
"department_access_1",
+5 -1
View File
@@ -2328,7 +2328,11 @@ test("superusers manage release settings, assignments, integrations, and sync op
await expect(page.getByTestId("release-assignment-subject-manual-user-909")).toContainText("User #909");
await expect(page.getByTestId("release-assignment-subject-manual-subuser-909")).toContainText("Subuser #909");
await expect(page.getByTestId("release-assignment-subject-manual-customer-909")).toContainText("Customer #909");
await page.getByTestId("release-assignment-subject-manual-subuser-909").click({ force: true });
await page
.getByTestId("release-assignment-subject-autocomplete")
.getByRole("button", { name: /Subuser #909/ })
.click();
await expect(assignmentSubjectInput).toHaveValue("Subuser #909 - Use typed value subuser:909");
await page.getByTestId("release-assignment-form").getByRole("button", { name: "Assign" }).click();
expect(state.assignmentPayloads[state.assignmentPayloads.length - 1]).toMatchObject({
subject_type: "subuser",
+1 -4
View File
@@ -27,10 +27,7 @@ async function primeSession(page, { token, permissions, sessionData = {} }) {
await seedAuthenticatedState(page, token);
}
async function mockSelectedSubuserGrant(
page,
{ customerNumber = 12345679, permissions = ["user", "SELFSERVE_LIST", "SELFSERVE_ADD"] } = {}
) {
async function mockSelectedSubuserGrant(page, { customerNumber = 12345679, permissions = ["SELFSERVE_LIST"] } = {}) {
await page.route("**/subusers/me", async (route) => {
await route.fulfill({
status: 200,
@@ -43,11 +43,46 @@ const departments = [
},
];
const roleTemplatePermissions = [
"user",
"permissions_list_own",
"list_departments",
"list_orders",
"fetch_order",
"statistics_orders_new",
];
const limitedBackofficePermissionTemplates = [
{
key: "viewer",
label: "Deactivated",
description: "Keeps the employee registered without order, booking, or management permissions.",
permissions: ["user", "permissions_list_own"],
},
{
key: "cashier",
label: "Cashier",
description: "Can work with POS orders for assigned departments.",
permissions: roleTemplatePermissions,
},
];
type PermissionCall = {
action: "add" | "remove";
permission: string;
};
const roleListEnvelope = (rows: Array<Record<string, unknown>>) => ({
data: rows,
meta: {
pagination: {
page: 1,
per_page: 100,
total: rows.length,
},
},
});
const openGroupTab = async (page: Page, label: RegExp) => {
await page.locator(".tabs").getByText(label).click();
};
@@ -147,6 +182,107 @@ const bootRolePermissionsPage = async (page: Page, routeOptions = {}) => {
};
test.describe("Superuser role permissions", () => {
test("applies limited backoffice templates from the role action wheel in add-only mode", async ({ page }) => {
const role = {
id: 2,
name: "Operations manager",
description: "Can manage operations.",
created_at: "2026-07-06T08:00:00.000Z",
permissions: ["user", "list_orders"],
};
const calls: PermissionCall[] = [];
await page.addInitScript(() => {
window.localStorage.setItem("locale", "en");
});
await seedAuthenticatedState(page, "superuser-roles-template-token");
await mockApi(page, {
authenticated: true,
permissions: ["superuser", "user", "list_roles", "add_role_permission"],
sessionData: {
group_id: 1,
},
});
await page.route(apiPathPattern("/roles/limited-backoffice-permission-templates"), async (route: Route) => {
await route.fulfill(json({ data: limitedBackofficePermissionTemplates }));
});
await page.route(apiPathPattern("/roles"), async (route: Route) => {
await route.fulfill(json(roleListEnvelope([role])));
});
await page.route(apiPathPattern("/roles/permissions"), async (route: Route) => {
const body = route.request().postDataJSON();
const permission = String(body.permission_id || "");
calls.push({ action: "add", permission });
if (!role.permissions.includes(permission)) {
role.permissions = [...role.permissions, permission];
}
await route.fulfill(json({ data: role }));
});
await page.goto("/superuser/roles", { waitUntil: "domcontentloaded" });
await expect(page.getByRole("row", { name: /Operations manager/ })).toBeVisible();
const row = page.getByRole("row", { name: /Operations manager/ });
await row.locator(".action-settings-wheel-trigger").click();
await expect(page.getByTestId("role-limited-backoffice-template-actions-2")).toBeVisible();
await page.getByTestId("role-template-2-cashier").click();
await expect(page.getByText("Apply permission template?")).toBeVisible();
await page.getByRole("button", { name: "Apply template" }).click();
await expect
.poll(() => calls.map((call) => call.permission))
.toEqual(["permissions_list_own", "list_departments", "fetch_order", "statistics_orders_new"]);
await expect(page.getByText("Template applied")).toBeVisible();
});
test("disables limited backoffice template actions when a role is already up to date", async ({ page }) => {
const role = {
id: 3,
name: "Cashier role",
description: "Current cashier permissions.",
created_at: "2026-07-06T08:00:00.000Z",
permissions: [...roleTemplatePermissions],
};
const calls: PermissionCall[] = [];
await page.addInitScript(() => {
window.localStorage.setItem("locale", "en");
});
await seedAuthenticatedState(page, "superuser-roles-template-up-to-date-token");
await mockApi(page, {
authenticated: true,
permissions: ["superuser", "user", "list_roles", "add_role_permission"],
sessionData: {
group_id: 1,
},
});
await page.route(apiPathPattern("/roles/limited-backoffice-permission-templates"), async (route: Route) => {
await route.fulfill(json({ data: limitedBackofficePermissionTemplates }));
});
await page.route(apiPathPattern("/roles"), async (route: Route) => {
await route.fulfill(json(roleListEnvelope([role])));
});
await page.route(apiPathPattern("/roles/permissions"), async (route: Route) => {
calls.push({ action: "add", permission: String(route.request().postDataJSON().permission_id || "") });
await route.fulfill(json({ data: role }));
});
await page.goto("/superuser/roles", { waitUntil: "domcontentloaded" });
const row = page.getByRole("row", { name: /Cashier role/ });
await expect(row).toBeVisible();
await row.locator(".action-settings-wheel-trigger").click();
await expect(page.getByTestId("role-template-3-cashier")).toBeDisabled();
expect(calls).toEqual([]);
});
test("@smoke @pr loads grouped permissions, searches, and toggles without a blank page", async ({ page }) => {
const { calls } = await bootRolePermissionsPage(page);
+125 -17
View File
@@ -35,6 +35,9 @@ const userEnvelope = (rows: Array<Record<string, unknown>>) => ({
},
});
const usersApiPattern =
/https?:\/\/(?:api\.truckwash\.io(?::\d+)?\/users|localhost(?::\d+)?\/api\/users|127\.0\.0\.1(?::\d+)?\/api\/users)(?:\?.*)?$/i;
const overviewUser = {
id: 11,
customer_number: 12345,
@@ -217,25 +220,22 @@ test.describe("Superuser employees list", () => {
},
});
await page.route(
/https?:\/\/(?:api\.truckwash\.io(?::\d+)?\/users|localhost(?::\d+)?\/api\/users|127\.0\.0\.1(?::\d+)?\/api\/users)(?:\?.*)?$/i,
async (route) => {
const request = route.request();
const url = new URL(request.url());
await page.route(usersApiPattern, async (route) => {
const request = route.request();
const url = new URL(request.url());
if (request.method() !== "GET") {
await route.fulfill(json({ data: { message: "OK" } }));
return;
}
const search = url.searchParams.get("search");
searchesSeen.push(search);
const normalizedSearch = String(search || "").toLowerCase();
const rows = normalizedSearch.includes("anna") ? [users[0]] : users;
await route.fulfill(json(userEnvelope(rows)));
if (request.method() !== "GET") {
await route.fulfill(json({ data: { message: "OK" } }));
return;
}
);
const search = url.searchParams.get("search");
searchesSeen.push(search);
const normalizedSearch = String(search || "").toLowerCase();
const rows = normalizedSearch.includes("anna") ? [users[0]] : users;
await route.fulfill(json(userEnvelope(rows)));
});
await page.goto("/superuser/users", { waitUntil: "domcontentloaded" });
@@ -258,6 +258,114 @@ test.describe("Superuser employees list", () => {
await expect(page.getByTestId("action-settings-wheel-section-customer")).toBeVisible();
expect(searchesSeen).toContain("Anna");
});
test("migrates an existing employee account into limited backoffice", async ({ page }, testInfo) => {
test.skip(!isDesktopProject(testInfo), "Desktop only");
await page.setViewportSize({ width: 1280, height: 720 });
await seedAuthenticatedState(page, "superuser-users-migration-token");
await mockApi(page, {
authenticated: true,
permissions: ["superuser", "user"],
sessionData: {
group_id: 1,
},
});
const legacyEmployee = {
id: 13,
customer_number: 0,
display_name: "Legacy Clerk",
group_id: 2,
limited_backoffice_managed: false,
};
const managedEmployee = {
id: 14,
customer_number: 0,
display_name: "Managed Clerk",
group_id: 77,
limited_backoffice_managed: true,
};
const customerUser = {
id: 15,
customer_number: 12345,
display_name: "Customer Account",
group_id: 2,
limited_backoffice_managed: false,
};
const rows = [legacyEmployee, managedEmployee, customerUser];
let usersRequests = 0;
let migrationPayload: unknown = null;
await page.route(usersApiPattern, async (route) => {
usersRequests += 1;
await route.fulfill(json(userEnvelope(rows)));
});
await page.route(apiPathPattern("/limited-backoffice/departments"), async (route) => {
await route.fulfill(
json({
data: [
{ id: 1, name: "Assigned Depot" },
{ id: 2, name: "Remote Depot" },
],
})
);
});
await page.route(apiPathPattern("/limited-backoffice/roles"), async (route) => {
await route.fulfill(
json({
data: [
{ key: "viewer", label: "Deactivated" },
{ key: "cashier", label: "Cashier" },
{ key: "department_admin", label: "Department admin" },
],
})
);
});
await page.route(apiPathPattern("/limited-backoffice/employees/13/migrate"), async (route) => {
if (route.request().method() !== "POST") {
await route.fulfill(json({ data: { message: "OK" } }));
return;
}
migrationPayload = await route.request().postDataJSON();
await route.fulfill(
json({
data: {
id: 13,
user_id: 13,
customer_number: 0,
display_name: "Legacy Clerk",
role: { key: "cashier", label: "Cashier" },
departments: [{ id: 1, name: "Assigned Depot" }],
active: true,
},
})
);
});
await page.goto("/superuser/users", { waitUntil: "domcontentloaded" });
await expect(page.getByTestId("superuser-users-row-13")).toContainText("Legacy Clerk");
await page.locator('[data-testid="superuser-user-actions-13"] .action-settings-wheel-trigger').click();
await expect(page.getByTestId("superuser-user-migrate-limited-13")).toBeVisible();
await page.getByTestId("superuser-user-migrate-limited-13").click();
await expect(page.locator(".swal2-popup")).toContainText("Migrate employee");
await page.locator(".limited-migration-department").first().check();
await page.locator(".swal2-confirm").click();
await expect.poll(() => migrationPayload).toEqual({ role_key: "cashier", department_ids: [1] });
await expect(page.locator(".swal2-popup")).toContainText("Employee migrated");
await page.locator(".swal2-confirm").click();
await expect.poll(() => usersRequests).toBeGreaterThan(1);
await page.locator('[data-testid="superuser-user-actions-14"] .action-settings-wheel-trigger').click();
await expect(page.getByTestId("superuser-user-migrate-limited-14")).toHaveCount(0);
await page.locator('[data-testid="superuser-user-actions-15"] .action-settings-wheel-trigger').click();
await expect(page.getByTestId("superuser-user-migrate-limited-15")).toHaveCount(0);
});
});
test.describe("Superuser user overview", () => {
@@ -491,6 +491,10 @@ describe("Periode tab contract", () => {
expect(xlvaskUsagePaginationSource).toContain('v-if="shouldShowLocalFilters"');
expect(xlvaskUsagePaginationSource).toContain('v-if="!hideSearchField && shouldShowLocalFilters"');
expect(xlvaskUsagePaginationSource).toContain('v-if="!props.loadAllAtOnce"');
expect(xlvaskUsagePaginationSource).toContain("const buildImportUsageParams = () => {");
expect(xlvaskUsagePaginationSource).toContain("dateFrom: props.initialDateFrom");
expect(xlvaskUsagePaginationSource).toContain("dateTo: props.initialDateTo");
expect(xlvaskUsagePaginationSource).toContain("buildImportUsageParams()");
});
it("loads Selvvask selector counts and progress from the selected period", () => {