Handle phone numbers
This commit is contained in:
parent
42fd2f1377
commit
b9f8e5d771
|
|
@ -12,6 +12,8 @@ import { getVVCourseName } from "./composables";
|
|||
import ItToggleSwitch from "@/components/ui/ItToggleSwitch.vue";
|
||||
import DatatransCembraDeviceFingerprint from "@/components/onboarding/DatatransCembraDeviceFingerprint.vue";
|
||||
import { getLocalSessionKey } from "@/statistics";
|
||||
import log from "loglevel";
|
||||
import { normalizeSwissPhoneNumber, validatePhoneNumber } from "@/utils/phone";
|
||||
|
||||
const props = defineProps({
|
||||
courseType: {
|
||||
|
|
@ -126,6 +128,14 @@ function validateAddress() {
|
|||
formErrors.value.personal.push(t("a.Land"));
|
||||
}
|
||||
|
||||
if (address.value.phone_number) {
|
||||
const normalizedPhoneNumber = normalizeSwissPhoneNumber(address.value.phone_number);
|
||||
log.debug("normalizedPhoneNumber", normalizedPhoneNumber);
|
||||
if (!validatePhoneNumber(normalizedPhoneNumber)) {
|
||||
formErrors.value.personal.push(t("a.Telefonnummer hat das falsche Format"));
|
||||
}
|
||||
}
|
||||
|
||||
if (withCembraInvoice.value) {
|
||||
if (!address.value.phone_number) {
|
||||
formErrors.value.personal.push(t("a.Telefonnummer"));
|
||||
|
|
@ -164,7 +174,8 @@ function validateAddress() {
|
|||
}
|
||||
|
||||
async function saveAddress() {
|
||||
const { country_code, organisation_country_code, ...profileData } = address.value;
|
||||
const { country_code, organisation_country_code, phone_number, ...profileData } =
|
||||
address.value;
|
||||
const typedProfileData: Partial<User> = { ...profileData };
|
||||
|
||||
typedProfileData.country = countries.value.find(
|
||||
|
|
@ -173,6 +184,7 @@ async function saveAddress() {
|
|||
typedProfileData.organisation_country = countries.value.find(
|
||||
(c) => c.country_code === organisation_country_code
|
||||
);
|
||||
typedProfileData.phone_number = normalizeSwissPhoneNumber(phone_number);
|
||||
|
||||
await user.updateUserProfile(typedProfileData);
|
||||
}
|
||||
|
|
@ -192,6 +204,8 @@ const executePayment = async () => {
|
|||
// anyway, so it seems fine to do it here.
|
||||
const fullHost = `${window.location.protocol}//${window.location.host}`;
|
||||
|
||||
address.value.phone_number = normalizeSwissPhoneNumber(address.value.phone_number);
|
||||
|
||||
itPost("/api/shop/vv/checkout/", {
|
||||
redirect_url: fullHost,
|
||||
address: address.value,
|
||||
|
|
@ -343,9 +357,7 @@ const executePayment = async () => {
|
|||
data-cy="continue-pay"
|
||||
@click="executePayment"
|
||||
>
|
||||
<template v-if="withCembraInvoice">
|
||||
TODO: Mit Rechnung/Cembra bezahlen
|
||||
</template>
|
||||
<template v-if="withCembraInvoice">TODO: Mit Rechnung/Cembra bezahlen</template>
|
||||
<template v-else>
|
||||
{{ $t("a.Mit Kreditkarte bezahlen") }}
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { normalizeSwissPhoneNumber, validatePhoneNumber } from "../phone";
|
||||
|
||||
describe("normalizeSwissPhoneNumber", () => {
|
||||
it("should normalize a Swiss phone number", () => {
|
||||
expect(normalizeSwissPhoneNumber("079 123 45 67")).toBe("+41791234567");
|
||||
expect(normalizeSwissPhoneNumber("00 41 79 123 45 67")).toBe("+41791234567");
|
||||
expect(normalizeSwissPhoneNumber("+41 (0)79 201 85 86")).toBe("+41792018586");
|
||||
expect(normalizeSwissPhoneNumber("+41 79 201 85 86")).toBe("+41792018586");
|
||||
});
|
||||
|
||||
it("should normalize remove spaces and special chars from foreign numbers", () => {
|
||||
expect(normalizeSwissPhoneNumber("+49 30 12345678")).toBe("+493012345678");
|
||||
expect(normalizeSwissPhoneNumber("+49-30-12345678")).toBe("+493012345678");
|
||||
|
||||
expect(normalizeSwissPhoneNumber("+33 1 23 45 67 89")).toBe("+33123456789");
|
||||
expect(normalizeSwissPhoneNumber("+33-1-23-45-67-89")).toBe("+33123456789");
|
||||
|
||||
expect(normalizeSwissPhoneNumber("+39 06 12345678")).toBe("+390612345678");
|
||||
expect(normalizeSwissPhoneNumber("+43 1 2345678")).toBe("+4312345678");
|
||||
expect(normalizeSwissPhoneNumber("+423 234 5678")).toBe("+4232345678");
|
||||
});
|
||||
});
|
||||
|
||||
describe("validatePhoneNumber", () => {
|
||||
it("should validate a Swiss phone number", () => {
|
||||
expect(validatePhoneNumber("079 123 45 67")).toBe(true);
|
||||
expect(validatePhoneNumber("00 41 79 123 45 67")).toBe(true);
|
||||
expect(validatePhoneNumber("+41 (0)79 201 85 86")).toBe(true);
|
||||
expect(validatePhoneNumber("+41 79 201 85 86")).toBe(true);
|
||||
expect(validatePhoneNumber("026 418 01 31")).toBe(true);
|
||||
|
||||
expect(validatePhoneNumber("+41 79 201 85 86 8")).toBe(false);
|
||||
expect(validatePhoneNumber("079 201 85 8")).toBe(false);
|
||||
expect(validatePhoneNumber("aaa aaa aaa aaa")).toBe(false);
|
||||
});
|
||||
|
||||
it("should validate a foreign phone number", () => {
|
||||
expect(validatePhoneNumber("+49 30 12345678")).toBe(true);
|
||||
expect(validatePhoneNumber("+49 30 1234567")).toBe(false);
|
||||
expect(validatePhoneNumber("+49 30 123456789")).toBe(false);
|
||||
|
||||
expect(validatePhoneNumber("+33 1 23 45 67 89")).toBe(true);
|
||||
expect(validatePhoneNumber("+33 1 23 45 67 89 9")).toBe(false);
|
||||
|
||||
expect(validatePhoneNumber("+39 06 12345678")).toBe(true);
|
||||
expect(validatePhoneNumber("+39 06 1234567")).toBe(false);
|
||||
|
||||
expect(validatePhoneNumber("+43 1 2345678")).toBe(true);
|
||||
expect(validatePhoneNumber("+43 1 23456789")).toBe(false);
|
||||
|
||||
expect(validatePhoneNumber("+423 235 09 09")).toBe(true);
|
||||
expect(validatePhoneNumber("+423 235 09 09 8")).toBe(false);
|
||||
|
||||
expect(validatePhoneNumber("+354 123 4567")).toBe(true);
|
||||
expect(validatePhoneNumber("+55 12 34567 8901")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
export function normalizeSwissPhoneNumber(input: string) {
|
||||
return input
|
||||
.replace(/\s+/g, "")
|
||||
.replace("(0)", "")
|
||||
.replaceAll("-", "")
|
||||
.replaceAll("/", "")
|
||||
.replaceAll("(", "")
|
||||
.replaceAll(")", "")
|
||||
.replace(/^0041/, "+41")
|
||||
.replace(/^\+410/, "+41")
|
||||
.replace(/^0/, "+41");
|
||||
}
|
||||
|
||||
export function validatePhoneNumber(input: string) {
|
||||
const normalized = normalizeSwissPhoneNumber(input);
|
||||
|
||||
if (
|
||||
!normalized.startsWith("+") ||
|
||||
isNaN(Number(normalized.slice(1))) ||
|
||||
normalized[1] === "0"
|
||||
) {
|
||||
// phone number can only start with a + and must be followed by numbers
|
||||
return false;
|
||||
}
|
||||
|
||||
if (["+41", "+43", "+49", "+39", "+33", "+42"].includes(normalized.slice(0, 3))) {
|
||||
if (
|
||||
// Swiss and French phone numbers
|
||||
(normalized.startsWith("+41") || normalized.startsWith("+33")) &&
|
||||
normalized.length === 12
|
||||
) {
|
||||
return true;
|
||||
} else if (
|
||||
// German and Italian phone numbers
|
||||
(normalized.startsWith("+49") || normalized.startsWith("+39")) &&
|
||||
normalized.length === 13
|
||||
) {
|
||||
return true;
|
||||
} else if (
|
||||
// Austrian and Liechtenstein phone numbers
|
||||
(normalized.startsWith("+43") || normalized.startsWith("+423")) &&
|
||||
normalized.length === 11
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// every other country
|
||||
if (normalized.length >= 10 || normalized.length <= 13) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function displaySwissPhoneNumber(input: string) {
|
||||
if (input && input.length === 12 && input.startsWith("+41")) {
|
||||
input = input.replace("+41", "0");
|
||||
let result = "";
|
||||
result += input.substring(0, 3) + " ";
|
||||
result += input.substring(3, 6) + " ";
|
||||
result += input.substring(6, 8) + " ";
|
||||
result += input.substring(8);
|
||||
return result;
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ describe("checkout.cy.js", () => {
|
|||
cy.get("#postal-code").type("1719");
|
||||
cy.get("#city").type("Zumholz");
|
||||
|
||||
cy.get("#phone").type("+41 79 201 85 86");
|
||||
cy.get("#phone").type("079 201 85 86");
|
||||
cy.get("#birth-date").type("1982-06-09");
|
||||
|
||||
cy.get('[data-cy="continue-pay"]').click();
|
||||
|
|
|
|||
Loading…
Reference in New Issue