define(["sprd/data/SprdModel", "js/data/Entity", "sprd/entity/Address", "sprd/model/ShippingType", "underscore", "js/data/validator/EmailValidator", "js/data/validator/RegExValidator", "js/data/transformer/TrimTransformer", "sprd/data/validator/LengthValidator"], function (SprdModel, Entity, Address, ShippingType, _, EmailValidator, RegExValidator, TrimTransformer, LengthValidator) {

    var Billing = Entity.inherit("sprd.model.Order.Billing", {
        defaults: {
            address: Address
        },

        schema: {
            address: Address
        }

    });


    var Shipping = Entity.inherit("sprd.model.Order.Shipping", {
        defaults: {
            address: Address,
            type: null
        },

        schema: {
            address: Address,
            type: ShippingType
        }
    });


    var Delivery = SprdModel.inherit("sprd.model.Delivery", {

        defaults: {
            billing: Billing,
            shipping: Shipping,

            email: null,
            phone: null,

            giftWrappingMessage: null,
            useGiftWrapping: false,

            invoiceToShippingAddress: true
        },

        $isDependentObject: true,

        schema: {
            shipping: Shipping,
            billing: Billing,


            email: String,

            giftWrappingMessage: {
                required: false,
                type: String
            },

            phone: {
                required: function () {
                    // required if shipping type is express
                    return this.get("shipping.type.isExpress");
                },
                type: String
            },

            useGiftWrapping: Boolean
        },

        reset: function () {
            this.set({
                email: null,
                phone: null,
                giftWrappingMessage: null,
                useGiftWrapping: false,
                invoiceToShippingAddress: true,
                billing: new Billing()
            });
        },

        transformers: [
            new TrimTransformer()
        ],

        validators: [
            new EmailValidator({field: "email"}),
            new RegExValidator({
                field: "phone",
                errorCode: "atLeast8Digits",
                regEx: /(.*\d.*){8}/
            }),
            new LengthValidator({
                field: "email",
                maxLength: 30
            })
        ],

        // TODO: add phone validator, checking DEV-68278 + shipping type determinates if optional or not

        compose: function () {
            var data = this.callBase();

            if (this.$.invoiceToShippingAddress) {
                delete data.billing;
            }

            if (!this.$.phone) {
                data.phone = null;
            }

            return data;
        },

        parse: function (data) {
            var billingAddress = this.get(data, 'billing.address'),
                shippingAddress = this.get(data, 'shipping.address');

            /**
             * we use the ids to determin if the billing address is the same as billing address
             * its a lil bit of a hack but faster than comparing all the fields.
             *
             * */
            if (billingAddress && shippingAddress) {
                this.set('invoiceToShippingAddress', shippingAddress.$.id == billingAddress.$.id);
            }

            if (this.$.invoiceToShippingAddress) {
                this.set('billing', new Billing());
                this.$.billing.$.address.set('id', "billing");
            } else if (billingAddress) {
                billingAddress.set('id', billingAddress.$.id || "billing");
            }

            if (shippingAddress) {
                shippingAddress.set('id', shippingAddress.$.id || "shipping");
            }
            return this.callBase();
        },

        invoiceAddress: function () {
            return this.$.invoiceToShippingAddress ? this.get("shipping.address") : this.get("billing.address");
        }.onChange("invoiceToShippingAddress", "billing.address", "shipping.address")

    });

    Delivery.Shipping = Shipping;
    Delivery.Billing = Billing;

    return Delivery;

});
@@ -2415,16 +2415,128 @@
 gth: 30%0A
+            %7D),%0A            new LengthValidator(%7B%0A                field: %22phone%22,%0A                maxLength: 30%0A
         

check phone number is maximum 30 chars long