Skip to content
Jerry Smidt edited this page Jan 25, 2024 · 8 revisions

How to exclude postcode ranges

Here's an example of additional validation that can be used to exclude certain postcode ranges. In this example we've excluded islands.

Edit the following files in your Magento module or create a new module and add them there. Make sure to change the validation to fit your needs (these are just examples).

Add dependency on Flekto_Postcode module:

etc/module.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="PostcodeEu_PostcodeRangeValidation">
        <sequence>
            <module name="Flekto_Postcode"/>
        </sequence>
    </module>
</config>

view/frontend/requirejs-config.js:

var config = {
	"config": {
		"mixins": {
            'Magento_Ui/js/lib/validation/validator': {
                'PostcodeEu_PostcodeRangeValidation/js/validation/validator-mixin-nl': true,
                'PostcodeEu_PostcodeRangeValidation/js/validation/validator-mixin-intl': true,
            },
			"Flekto_Postcode/js/form/element/postcode": {
				"PostcodeEu_PostcodeRangeValidation/js/form/element/postcode-mixin": true
			},
			"Flekto_Postcode/js/form/element/address-autofill-intl": {
				"PostcodeEu_PostcodeRangeValidation/js/form/element/address-autofill-intl-mixin": true
			},
		},
	},
};

view/frontend/web/js/form/element:

define([], function () {
    'use strict';

    return function (Component) {
        return Component.extend({
            defaults : {
                validation: {
                    'validate-wadden-nl': '${ $.parentScope }',
                },
            },
        });
    };
});

view/frontend/web/js/validation/validator-mixin-nl.js:

/*!
 * Validator mixin for Magento_Ui/js/lib/validation/validator
 */
define([
    'mage/translate',
], function ($t) {
    'use strict';

    return function (validator) {

        validator.addRule(
            'validate-wadden-nl',
            function (value, parentScope) {
                if (parentScope.split('.')[0] !== 'shippingAddress') {
                    return true
                }

                // Texel: 1790 - 1797
                // Vlieland: 8899
                // Terschelling: 8880 - 8885
                // Ameland: 9160 - 9164
                // Schiermonnikoog: 9166
                const regex = /^(179[0-7]|8899|888[0-5]|916[0-4]|9166)/;
                return value === '' || regex.test(value) === false;
            },
            $t('Sorry, wij bezorgen niet op dit Waddeneiland.')
        );

        return validator;
    };
});

view/frontend/web/js/form/element/address-autofill-intl-mixin.js:

define([], function () {
    'use strict';

    return function (Component) {
        return Component.extend({
            initialize: function () {
                this._super();
                this.validation['validate-excluded-shipping-locations'] = this;
                return this;
            },
        });
    }
})

view/frontend/web/js/validation/validator-mixin-intl.js:

/*!
 * Validator mixin for Magento_Ui/js/lib/validation/validator
 */
define([
    'mage/translate',
], function ($t) {
    'use strict';

    return function (validator) {

        // Regex patterns for postcode ranges to exclude from the shipping address.
        // Modify as needed.
        const excludedPostcodeRanges = {
            'NL':
                // Texel: 1790 - 1797
                // Vlieland: 8899
                // Terschelling: 8880 - 8885
                // Ameland: 9160 - 9164
                // Schiermonnikoog: 9166
                /^(179[0-7]|8899|888[0-5]|916[0-4]|9166)/,
            'DE':
                // Borkum: 26757
                // Juist: 26571
                // Norderney: 26548
                // Baltrum: 26579
                // Langeoog: 26465
                // Spiekeroog: 26474
                // Wangerooge: 26486
                // Sylt: 25980, 25992 - 25999
                // Föhr: 25938
                // Amrum: 25946
                /^(26757|26571|26548|26579|26465|26474|26486|25980|2599[2-9]|25938|25946)$/,
            'DK':
                // Bornholm: 37**
                // Ærø: 5970, 5985, 5960
                // Fanø: 6720
                // Samsø: 8305
                // Læsø: 9940
                /^(37\d\d|5970|5985|5960|6720|8305|9940)$/,
            'FR':
                // Corsica: 20***
                /^20/,
            'ES':
                // Balearic Islands: 07***
                // Province of Las Palmas: 35***
                // Province of Santa Cruz de Tenerife: 38***
                // Ceuta: 51001 - 51005
                // Melilla: 52001 - 52006
                /^(07|35|38|5100[1-5]|5200[1-6])/,
            'GB':
                // Isle of Man: IM1 - IM99
                // Jersey: JE1 - JE5
                // Guernsey: GY1 - GY8
                // Outer Hebrides / Western Isles: HS1 - HS9
                // Shetland: ZE1 - ZE3
                /^(IM\d|JE[1-5]|GY[1-8]|HS\d|ZE[1-3])/,
        };

        validator.addRule(
            'validate-excluded-shipping-locations',
            function (_, intlField) {
                if (
                    typeof excludedPostcodeRanges[intlField.countryCode] === 'undefined'
                    || intlField.parentScope !== 'shippingAddress'
                    || intlField.visible() === false
                    || intlField.address() === null
                ) {
                    return true;
                }

                const postcode = intlField.address().address.postcode;
                return false === excludedPostcodeRanges[intlField.countryCode].test(postcode);
            },
            $t('Sorry, we do not ship to this location.')
        );

        return validator;
    };
});
Clone this wiki locally