Test cembra/byjuno invoice

This commit is contained in:
Daniel Egger 2024-06-27 18:09:21 +02:00
parent 052b07eabf
commit fab9297989
7 changed files with 75 additions and 39 deletions

View File

@ -1,6 +1,7 @@
<script setup lang="ts">
import { computed } from "vue";
import { useEntities } from "@/services/entities";
import { t } from "i18next";
const props = defineProps<{
modelValue: {
@ -11,6 +12,7 @@ const props = defineProps<{
postal_code: string;
city: string;
country_code: string;
payment_method: string;
phone_number: string;
birth_date: string;
@ -21,6 +23,13 @@ const emit = defineEmits(["update:modelValue"]);
const { countries } = useEntities();
const paymentMethods = computed(() => {
return [
{ value: "credit_card", label: t("a.Debit-/Kreditkarte / Twint") },
{ value: "cembra_byjuno", label: t("a.Rechnung") },
];
});
const address = computed({
get() {
return props.modelValue;
@ -168,6 +177,35 @@ const address = computed({
</div>
<div class="col-span-full">
<label
for="paymentMethod"
class="block text-sm font-medium leading-6 text-gray-900"
>
{{ $t("a.Zahlungsart") }}
</label>
<div class="mt-2">
<select
id="paymentMethod"
v-model="address.payment_method"
required
name="paymentMethod"
class="block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:text-sm sm:leading-6"
>
<option v-for="pm in paymentMethods" :key="pm.value" :value="pm.value">
{{ pm.label }}
</option>
</select>
</div>
</div>
<div v-if="address.payment_method === 'cembra_byjuno'" class="col-span-full">
<p class="mt-4">
TODO: Eine Zahlung mit Rechnung wird immer auf deine Privatadresse verrechnet.
Du musst zwinged deine Telefonnummer und dein Geburtsdatum angeben.
</p>
</div>
<div v-if="address.payment_method === 'cembra_byjuno'" class="col-span-full">
<label for="phone" class="block text-sm font-medium leading-6 text-gray-900">
{{ $t("a.Telefonnummer") }}
</label>
@ -183,7 +221,7 @@ const address = computed({
</div>
</div>
<div class="col-span-full">
<div v-if="address.payment_method === 'cembra_byjuno'" class="col-span-full">
<label for="birth-date" class="block text-sm font-medium leading-6 text-gray-900">
{{ $t("a.Geburtsdatum") }}
</label>

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import WizardPage from "@/components/onboarding/WizardPage.vue";
import { computed, ref } from "vue";
import { computed, ref, watch } from "vue";
import { type User, useUserStore } from "@/stores/user";
import PersonalAddress from "@/components/onboarding/PersonalAddress.vue";
import OrganisationAddress from "@/components/onboarding/OrganisationAddress.vue";
@ -56,6 +56,8 @@ const address = ref({
city: user.city,
country_code: user.country?.country_code ?? "CH",
payment_method: "credit_card",
phone_number: user.phone_number,
birth_date: user.birth_date,
@ -75,14 +77,14 @@ const setWithCompanyAddress = (value: boolean) => {
address.value.invoice_address = value ? "org" : "prv";
};
const withCembraInvoice = ref<boolean>(false);
function toggleCembraInvoice() {
withCembraInvoice.value = !withCembraInvoice.value;
if (!withCembraInvoice.value) {
setWithCompanyAddress(false);
watch(
() => address.value.payment_method,
(newValue) => {
if (newValue === "cembra_byjuno") {
setWithCompanyAddress(false);
}
}
}
);
type FormErrors = {
personal: string[];
@ -136,7 +138,7 @@ function validateAddress() {
}
}
if (withCembraInvoice.value) {
if (address.value.payment_method === "cembra_byjuno") {
if (!address.value.phone_number) {
formErrors.value.personal.push(t("a.Telefonnummer"));
}
@ -211,11 +213,14 @@ const executePayment = async () => {
address.value.phone_number = normalizeSwissPhoneNumber(address.value.phone_number);
}
const addressData = Object.assign({}, address.value);
delete addressData.payment_method;
itPost("/api/shop/vv/checkout/", {
redirect_url: fullHost,
address: address.value,
address: addressData,
product: props.courseType,
with_cembra_invoice: withCembraInvoice.value,
with_cembra_byjuno_invoice: address.value.payment_method === "cembra_byjuno",
device_fingerprint_session_key: getLocalSessionKey(),
}).then((res: any) => {
console.log("Going to next page", res.next_step_url);
@ -227,7 +232,9 @@ const executePayment = async () => {
<template>
<WizardPage :step="2">
<template #content>
<DatatransCembraDeviceFingerprint v-if="withCembraInvoice" />
<DatatransCembraDeviceFingerprint
v-if="address.payment_method === 'cembra_byjuno'"
/>
<h2 class="my-10" data-cy="account-checkout-title">
{{ $t("a.Lehrgang kaufen") }}
</h2>
@ -281,24 +288,7 @@ const executePayment = async () => {
{{ formErrors.personal.join(", ") }}
</p>
<div class="flex flex-row items-center space-x-2 text-sm">
<ItToggleSwitch
data-cy="cembra-switch"
:initially-switched-left="withCembraInvoice"
@click="toggleCembraInvoice()"
></ItToggleSwitch>
<span :class="{ 'text-gray-700': !withCembraInvoice }">
"TODO: Zahlung auf Rechnung/Cembra"
</span>
</div>
<section v-if="withCembraInvoice">
<p class="mt-4">
TODO: Bei Zahlung auf Rechnung/Cembra, wird immer auf deine Privatadresse
verrechnet. Du musst zwinged deine Telefonnummer und Geburtsdatum angeben.
</p>
</section>
<section v-else>
<section v-if="address.payment_method !== 'cembra_byjuno'">
<div class="mt-4">
<button
v-if="!withCompanyAddress"
@ -362,7 +352,9 @@ const executePayment = async () => {
data-cy="continue-pay"
@click="executePayment"
>
<template v-if="withCembraInvoice">TODO: Mit Rechnung/Cembra bezahlen</template>
<template v-if="address.payment_method === 'cembra_byjuno'">
{{ $t("a.Mit Rechnung bezahlen") }}
</template>
<template v-else>
{{ $t("a.Mit Kreditkarte bezahlen") }}
</template>

View File

@ -119,7 +119,8 @@ describe("checkout.cy.js", () => {
"contain",
"Lehrgang kaufen"
);
cy.get('[data-cy="cembra-switch"]').click();
cy.get('#paymentMethod').select('cembra_byjuno');
cy.get("#street-address").type("Eggersmatt");
cy.get("#street-number").type("32");
@ -169,7 +170,7 @@ describe("checkout.cy.js", () => {
expect(ci.country).to.equal("CH");
expect(ci.phone_number).to.equal("+41792018586");
expect(ci.birth_date).to.equal("1982-06-09");
expect(ci.cembra_invoice).to.be.true;
expect(ci.cembra_byjuno_invoice).to.be.true;
expect(ci.invoice_address).to.equal("prv");

View File

@ -16,7 +16,7 @@ class Migration(migrations.Migration):
),
migrations.AddField(
model_name="checkoutinformation",
name="cembra_invoice",
name="cembra_byjuno_invoice",
field=models.BooleanField(default=False),
),
migrations.AddField(

View File

@ -79,7 +79,7 @@ class CheckoutInformation(models.Model):
)
# optional fields for cembra payment
cembra_invoice = models.BooleanField(default=False)
cembra_byjuno_invoice = models.BooleanField(default=False)
birth_date = models.DateField(null=True, blank=True)
phone_number = models.CharField(max_length=255, blank=True, default="")
email = models.CharField(max_length=255, blank=True, default="")

View File

@ -80,6 +80,7 @@ def init_datatrans_transaction(
datatrans_customer_data: dict = None,
datatrans_int_data: dict = None,
context_data: dict = None,
with_cembra_byjuno_invoice: bool = False,
):
payload = {
# We use autoSettle=True, so that we don't have to settle the transaction:
@ -97,6 +98,9 @@ def init_datatrans_transaction(
},
}
# FIXME: test with working cembra byjuno invoice customer?
# if with_cembra_byjuno_invoice:
# payload["paymentMethods"] = ["INT"]
if datatrans_customer_data:
payload["customer"] = datatrans_customer_data
if datatrans_int_data:

View File

@ -111,14 +111,14 @@ def checkout_vv(request):
if checkouts.filter(state=CheckoutState.PAID).exists():
return next_step_response(url="/")
with_cembra_invoice = request.data.get("with_cembra_invoice", False)
with_cembra_byjuno_invoice = request.data.get("with_cembra_byjuno_invoice", False)
ip_address = request.META.get("REMOTE_ADDR")
email = request.user.email
try:
datatrans_customer_data = None
datatrans_int_data = None
if with_cembra_invoice:
if with_cembra_byjuno_invoice:
if "fakeapi" not in settings.DATATRANS_API_ENDPOINT:
request.user.set_increment_abacus_debitor_number()
@ -158,6 +158,7 @@ def checkout_vv(request):
datatrans_customer_data=datatrans_customer_data,
datatrans_int_data=datatrans_int_data,
context_data=context_data,
with_cembra_byjuno_invoice=with_cembra_byjuno_invoice,
)
except InitTransactionException as e:
if not settings.DEBUG:
@ -193,7 +194,7 @@ def checkout_vv(request):
product_description=product.description,
email=email,
ip_address=ip_address,
cembra_invoice=with_cembra_invoice,
cembra_byjuno_invoice=with_cembra_byjuno_invoice,
device_fingerprint_session_key=request.data.get(
"device_fingerprint_session_key", ""
),