Passed
Pull Request — master (#74)
by oleksandr
05:10
created

src/SprykerEco/Yves/Payone/Theme/default/components/molecules/payone-klarna/payone-klarna.ts   A

Complexity

Total Complexity 12
Complexity/F 1.2

Size

Lines of Code 178
Function Count 10

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 140
mnd 2
bc 2
fnc 10
dl 0
loc 178
bpm 0.2
cpm 1.2
noi 0
c 0
b 0
f 0
rs 10

10 Functions

Rating   Name   Duplication   Size   Complexity  
A PayoneKlarna.loadKlarna 0 20 1
A PayoneKlarna.mapScriptLoadEvent 0 3 1
A PayoneKlarna.readyCallback 0 2 1
A PayoneKlarna.init 0 6 1
A PayoneKlarna.mapEvents 0 4 1
A PayoneKlarna.selectPaymentMethod 0 4 1
A PayoneKlarna.klarnaPayMethods 0 3 1
A PayoneKlarna.getAvailablePaymentMethods 0 27 3
A PayoneKlarna.mapSelectChangeEvent 0 3 1
A PayoneKlarna.toggleSelectFieldDisable 0 3 1
1
/* tslint:disable: max-file-line-count */
2
3
import Component from 'ShopUi/models/component';
4
import ScriptLoader from 'ShopUi/components/molecules/script-loader/script-loader';
5
6
declare const Klarna;
7
const TOKEN_CONTAINER_ID = 'paymentForm_payoneKlarna_payMethodToken';
8
const IS_VALID_PARAM = 'is_valid';
9
const GET_TOKEN_URL = '/payone/get-token';
10
const CONTAINER_ID = '#klarna_container';
11
12
interface PaymentData {
13
    'client_token': string;
14
    'pay_method': string;
15
}
16
17
interface KlarnaPayMethods {
18
    KDD: string;
19
    KIS: string;
20
    KIV: string;
21
}
22
23
interface AddressData {
24
    'given_name': string;
25
    'family_name': string;
26
    'email': string;
27
    'street_address': string;
28
    'postal_code': string;
29
    'city': string;
30
    'country': string;
31
    'phone': string;
32
}
33
34
export default class PayoneKlarna extends Component {
35
    protected scriptLoader: ScriptLoader;
36
    protected selectField: HTMLSelectElement;
37
    protected availablePayment: PaymentData;
38
    protected availablePaymentArray: PaymentData[] = [];
39
    protected currentPaymentMethodCategory: string;
40
    protected currentPaymentCompanyToken: string;
41
    protected allKlarnaPayMethods: KlarnaPayMethods;
42
    protected addressData: AddressData = {
43
        'given_name': this.givenName,
44
        'family_name': this.familyName,
45
        'email': this.email,
46
        'street_address': this.streetAddress,
47
        'postal_code': this.postalCode,
48
        'city': this.city,
49
        'country': this.country,
50
        'phone': this.phone,
51
    }
52
53
    protected readyCallback(): void {}
54
55
    protected init(): void {
56
        this.scriptLoader = <ScriptLoader>this.getElementsByClassName(`${this.jsName}__script-loader`)[0];
57
        this.selectField = <HTMLSelectElement>this.getElementsByClassName(`${this.jsName}__select-field`)[0];
58
        this.allKlarnaPayMethods = <KlarnaPayMethods>JSON.parse(this.klarnaPayMethods());
59
60
        this.mapEvents();
61
    }
62
63
    protected mapEvents(): void {
64
        this.mapScriptLoadEvent();
65
        this.mapSelectChangeEvent();
66
    }
67
68
    protected mapScriptLoadEvent(): void {
69
        this.scriptLoader.addEventListener('scriptload', () => this.getAvailablePaymentMethods());
70
    }
71
72
    protected mapSelectChangeEvent(): void {
73
        this.selectField.addEventListener('change', () => this.selectPaymentMethod());
74
    }
75
76
    protected getAvailablePaymentMethods(): void {
77
        Array.from(this.selectField.options).forEach(option => {
78
            if (!option.value) {
79
                return;
80
            }
81
82
            const formData = new FormData();
83
            formData.append('pay_method', option.value);
84
85
            fetch(GET_TOKEN_URL, {method: 'POST', body: formData})
86
                .then(response => response.json())
87
                .then(parsedResponse => {
88
                    if (!parsedResponse[IS_VALID_PARAM]) {
89
                        return;
90
                    }
91
92
                    this.availablePayment = {
93
                        'pay_method': option.value,
94
                        'client_token': parsedResponse.client_token,
95
                    };
96
97
                    this.availablePaymentArray.push(this.availablePayment);
98
                    option.removeAttribute('disabled');
99
                })
100
                .catch((error: Error) => {
101
                    console.error(error.message);
102
                });
103
        });
104
    }
105
106
    protected selectPaymentMethod(): void {
107
        const paymentMethod = this.availablePaymentArray.find(payment => payment.pay_method === this.selectField.value);
108
        this.loadKlarna(paymentMethod);
109
    }
110
111
    protected loadKlarna(paymentData: PaymentData): void {
112
        this.toggleSelectFieldDisable(true);
113
114
        Klarna.Payments.init({ client_token: paymentData.client_token });
115
        Klarna.Payments.load({
116
            container: CONTAINER_ID,
117
            payment_method_category: this.allKlarnaPayMethods[paymentData.pay_method],
118
        },  response => {
119
            this.toggleSelectFieldDisable(false);
120
            Klarna.Payments.authorize({
121
                payment_method_category: this.allKlarnaPayMethods[paymentData.pay_method],
122
            }, {
123
                billing_address: this.addressData,
124
                customer: {
125
                    date_of_birth: this.dateOfBirth,
126
                },
127
            }, response => {
128
                const tokenContainer = <HTMLInputElement>document.getElementById(TOKEN_CONTAINER_ID);
129
                tokenContainer.value = response.authorization_token;
130
            })
131
        })
132
    }
133
134
    protected toggleSelectFieldDisable(isSelectDisabled: boolean): void {
135
        this.selectField.disabled = isSelectDisabled;
136
    }
137
138
    protected get givenName(): string {
139
        return this.getAttribute('given-name');
140
    }
141
142
    protected get familyName(): string {
143
        return this.getAttribute('family-name');
144
    }
145
146
    protected get email(): string {
147
        return this.getAttribute('email');
148
    }
149
150
    protected get streetAddress(): string {
151
        return this.getAttribute('street-address');
152
    }
153
154
    protected get postalCode(): string {
155
        return this.getAttribute('postal-code');
156
    }
157
158
    protected get city(): string {
159
        return this.getAttribute('city');
160
    }
161
162
    protected get country(): string {
163
        return this.getAttribute('country');
164
    }
165
166
    protected get phone(): string {
167
        return this.getAttribute('phone');
168
    }
169
170
    protected get dateOfBirth(): string {
171
        return this.getAttribute('date-of-birth');
172
    }
173
174
    protected klarnaPayMethods(): string {
175
        return this.getAttribute('klarna-pay-methods');
176
    }
177
}
178