174 lines
6.6 KiB
JavaScript
174 lines
6.6 KiB
JavaScript
/**
|
|
* Forms Component - Handles form data and validation
|
|
*/
|
|
const FormsComponent = {
|
|
/**
|
|
* Initialize forms state
|
|
* @returns {Object}
|
|
*/
|
|
getInitialState() {
|
|
return {
|
|
form: {
|
|
initials: '',
|
|
lastname: '',
|
|
postcode: '',
|
|
houseno: '',
|
|
suffix: '',
|
|
street: '',
|
|
city: '',
|
|
email: '',
|
|
phone: ''
|
|
},
|
|
meta: {
|
|
mediacode: ''
|
|
},
|
|
addressError: ''
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Get forms methods for Alpine.js component
|
|
* @returns {Object}
|
|
*/
|
|
getMethods() {
|
|
return {
|
|
/**
|
|
* Format initials with dots (e.g., "JK" -> "J.K.")
|
|
*/
|
|
formatInitials() {
|
|
let v = this.form.initials.replace(/[^a-z]/gi, '').toUpperCase();
|
|
this.form.initials = v.split('').join('.') + (v ? '.' : '');
|
|
},
|
|
|
|
/**
|
|
* Capitalize first letter of lastname
|
|
*/
|
|
formatLastname() {
|
|
this.form.lastname = this.form.lastname.charAt(0).toUpperCase() + this.form.lastname.slice(1);
|
|
},
|
|
|
|
/**
|
|
* Lookup address by postcode and house number
|
|
*/
|
|
async lookupAddress() {
|
|
this.addressError = '';
|
|
|
|
if (this.form.postcode.length >= 6 && this.form.houseno) {
|
|
try {
|
|
const data = await ApiService.lookupPostcode(this.form.postcode, this.form.houseno);
|
|
|
|
if (data.street) {
|
|
this.form.street = data.street.toUpperCase();
|
|
this.form.city = data.city.toUpperCase();
|
|
} else if (data.error) {
|
|
this.addressError = data.error;
|
|
} else {
|
|
this.addressError = 'Adres niet gevonden';
|
|
}
|
|
} catch (e) {
|
|
this.addressError = 'Fout bij ophalen adres';
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Reset form for new order
|
|
*/
|
|
resetForm() {
|
|
this.form = {
|
|
initials: '',
|
|
lastname: '',
|
|
postcode: '',
|
|
houseno: '',
|
|
suffix: '',
|
|
street: '',
|
|
city: '',
|
|
email: '',
|
|
phone: ''
|
|
};
|
|
this.addressError = '';
|
|
},
|
|
|
|
/**
|
|
* Build order payload from form data
|
|
* Includes prices from sales screen to ensure discounts and free items are applied correctly
|
|
* @returns {Object}
|
|
*/
|
|
buildOrderPayload() {
|
|
const address = (this.form.street + ' ' + this.form.houseno + ' ' + (this.form.suffix || '')).trim();
|
|
|
|
return {
|
|
mediacode_internal: this.meta.mediacode,
|
|
shipping_total: this.shipping,
|
|
billing: {
|
|
first_name: this.form.initials,
|
|
last_name: this.form.lastname,
|
|
address_1: address,
|
|
city: this.form.city,
|
|
postcode: this.form.postcode,
|
|
country: 'NL',
|
|
email: this.form.email,
|
|
phone: this.form.phone
|
|
},
|
|
shipping: {
|
|
first_name: this.form.initials,
|
|
last_name: this.form.lastname,
|
|
address_1: address,
|
|
city: this.form.city,
|
|
postcode: this.form.postcode,
|
|
country: 'NL',
|
|
email: this.form.email,
|
|
phone: this.form.phone
|
|
},
|
|
line_items: this.cart.map(i => {
|
|
// Calculate price excluding VAT (21%)
|
|
const priceExclVat = (parseFloat(i.price) / 1.21).toFixed(4);
|
|
|
|
// For free items, use originalPrice if available, otherwise use price
|
|
const originalPriceExclVat = i.originalPrice
|
|
? (parseFloat(i.originalPrice) / 1.21).toFixed(4)
|
|
: priceExclVat;
|
|
|
|
// Build line item object
|
|
const lineItem = {
|
|
product_id: i.id,
|
|
variation_id: i.variation_id || 0,
|
|
quantity: 1,
|
|
// Set subtotal and total to override WooCommerce's price calculation
|
|
// subtotal = price before line-level discounts (shows original value)
|
|
// total = price after line-level discounts (actual charged amount)
|
|
subtotal: i.isFree ? originalPriceExclVat : priceExclVat,
|
|
total: i.isFree ? '0.0000' : priceExclVat
|
|
};
|
|
|
|
// Add metadata for tracking discounts and free items
|
|
if (i.isFree) {
|
|
lineItem.meta_data = [
|
|
{ key: '_is_free_item', value: 'yes' },
|
|
{ key: '_bogo_rule_id', value: String(i.ruleId || '') },
|
|
{ key: '_original_price_incl_vat', value: String(i.originalPrice || i.price) }
|
|
];
|
|
} else if (i.isDiscounted) {
|
|
lineItem.meta_data = [
|
|
{ key: '_is_discounted_item', value: 'yes' },
|
|
{ key: '_original_price_incl_vat', value: String(i.originalPrice || '') },
|
|
{ key: '_bogo_rule_id', value: String(i.ruleId || '') }
|
|
];
|
|
}
|
|
|
|
return lineItem;
|
|
})
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Validate form before submission
|
|
* @returns {boolean}
|
|
*/
|
|
isFormValid() {
|
|
return this.form.email && this.meta.mediacode && this.cart.length > 0;
|
|
}
|
|
};
|
|
}
|
|
};
|