From 80924ff66c059a95e1d28f0efbf7dddaabe72fce Mon Sep 17 00:00:00 2001 From: Gaurav Goyal Date: Thu, 25 Sep 2014 11:12:09 +0530 Subject: [PATCH] Add phone number while creating or editing address #5731 --- checkout.py | 137 ++++++++++++++++++++++++++++++++++++++++- tests/test_checkout.py | 87 ++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 1 deletion(-) diff --git a/checkout.py b/checkout.py index f8d265f..8f22232 100755 --- a/checkout.py +++ b/checkout.py @@ -7,11 +7,12 @@ :copyright: (c) 2010-2014 by Openlabs Technologies & Consulting (P) LTD. :license: GPLv3, see LICENSE for more details """ +import warnings from datetime import datetime from functools import wraps from nereid import render_template, request, url_for, flash, redirect, \ - current_app, current_user, route + current_app, current_user, route, abort, login_required from nereid.signals import failed_login from nereid.globals import session from flask.ext.login import login_user @@ -22,6 +23,7 @@ from trytond.model import ModelView, fields from trytond.pool import Pool, PoolMeta from trytond.transaction import Transaction +from jinja2 import TemplateNotFound from trytond.pyson import Eval from .i18n import _ @@ -768,3 +770,136 @@ class Address: ('party', '=', Eval('party')) ], depends=['party'], select=True ) + + @classmethod + @route("/create-address", methods=["GET", "POST"]) + @login_required + def create_address(cls): + """ + Create an address for the current nereid_user + + This method is extension of nereid method for creating + address. Change in this method is adding phone_number contact mech + to address via address form field phone. + + If form data is coming from phone field add phone_number else do not + pass phone number + """ + form = cls.get_address_form() + + if request.method == 'POST' and form.validate(): + + address_dict = { + 'name': form.name.data, + 'street': form.street.data, + 'streetbis': form.streetbis.data, + 'zip': form.zip.data, + 'city': form.city.data, + 'country': form.country.data, + 'subdivision': form.subdivision.data, + 'party': current_user.party.id, + } + + if form.phone.data: + phone_number = \ + current_user.party.add_contact_mechanism_if_not_exists( + 'phone', form.phone.data + ) + address_dict.update({ + 'phone_number': phone_number.id, + }) + + address, = cls.create([address_dict]) + + if form.email.data: + current_user.party.add_contact_mechanism_if_not_exists( + 'email', form.email.data + ) + + return redirect(url_for('party.address.view_address')) + + try: + return render_template('address-add.jinja', form=form) + except TemplateNotFound: + # The address-add template was introduced in 3.0.3.0 + # so just raise a deprecation warning till 3.2.X and then + # expect the use of address-add template + warnings.warn( + "address-add.jinja template not found. " + "Will be required in future versions", + DeprecationWarning + ) + return render_template('address-edit.jinja', form=form) + + @classmethod + @route("/save-new-address", methods=["GET", "POST"]) + @route("/edit-address/", methods=["GET", "POST"]) + @login_required + def edit_address(cls, address=None): + """ + Edit an Address + + POST will update an existing address. + GET will return a existing address edit form. + + This method is extension of nereid patry address method. + + In this method we are mapping phone number to address + and redirecting to desired url passed by template request. + """ + + if address is None: + warnings.warn( + "Address creation will be deprecated from edit_address handler." + " Use party.address.create_address instead", + DeprecationWarning + ) + return cls.create_address() + + form = cls.get_address_form() + + if address not in (a.id for a in request.nereid_user.party.addresses): + # Check if the address is in the list of addresses of the + # current user's party + abort(403) + + address = cls(address) + + if request.method == 'POST' and form.validate(): + + address_dict = { + 'name': form.name.data, + 'street': form.street.data, + 'streetbis': form.streetbis.data, + 'zip': form.zip.data, + 'city': form.city.data, + 'country': form.country.data, + 'subdivision': form.subdivision.data, + } + + if form.phone.data: + phone_number = \ + current_user.party.add_contact_mechanism_if_not_exists( + 'phone', form.phone.data + ) + address_dict.update({ + 'phone_number': phone_number.id, + }) + + cls.write([address], address_dict) + + if form.email.data: + current_user.party.add_contact_mechanism_if_not_exists( + 'email', form.email.data + ) + + if not current_user.is_anonymous() and request.args.get('next'): + return redirect(request.args['next']) + + return redirect(url_for('party.address.view_address')) + + elif request.method == 'GET' and address: + # Its an edit of existing address, prefill data + form = cls.get_address_form(address) + + return render_template('address-edit.jinja', form=form, address=address) diff --git a/tests/test_checkout.py b/tests/test_checkout.py index 5093801..f54ddd4 100644 --- a/tests/test_checkout.py +++ b/tests/test_checkout.py @@ -49,6 +49,8 @@ def setUp(self): 'emails/sale-confirmation-text.jinja': ' ', 'emails/sale-confirmation-html.jinja': ' ', 'checkout.jinja': '{{form.errors|safe}}', + 'address-edit.jinja': '{{ form.errors|safe }} ', + 'address-add.jinja': ' ', }) # Patch SMTP Lib @@ -716,6 +718,91 @@ def test_0060_regd_user_wrong_address(self): ) self.assertEqual(len(sales), 1) + def test_0070_regd_user_add_and_edit_address(self): + """ + Registered user will add address from account page + and edit from the shipping address page. + """ + with Transaction().start(DB_NAME, USER, CONTEXT): + self.setup_defaults() + app = self.get_app() + + NereidUser = POOL.get('nereid.user') + Address = POOL.get('party.address') + + country = self.Country(self.available_countries[0]) + subdivision = country.subdivisions[0] + + user, = NereidUser.search([ + ('email', '=', 'email@example.com') + ]) + + with app.test_client() as c: + + # Sign-in + c.post( + '/login', data={ + 'email': 'email@example.com', + 'password': 'password', + } + ) + c.post( + '/create-address', data={ + 'name': 'Sharoon Thomas', + 'street': 'Biscayne Boulevard', + 'streetbis': 'Apt. 1906, Biscayne Park', + 'zip': 'FL33137', + 'city': 'Miami', + 'country': country.id, + 'subdivision': subdivision.id, + } + ) + address, = Address.search([ + ('party', '=', user.party.id), + ('name', '=', 'Sharoon Thomas'), + ]) + + self.assertTrue(address) + + c.post( + '/cart/add', data={ + 'product': self.product1.id, 'quantity': 5 + } + ) + + rv = c.post('/edit-address/22') + + self.assertEqual(rv.status_code, 403) + + rv = c.get( + '/edit-address/%d' % ( + address.id, + ) + '?next=%2Fcheckout%2Fshipping-address' + ) + self.assertEqual(rv.status_code, 200) + + rv = c.post( + '/edit-address/%d' % ( + address.id, + ) + '?next=%2Fcheckout%2Fshipping-address', data={ + 'name': 'Sharoon Thomas', + 'street': 'Biscayne Boulevard', + 'streetbis': 'Apt. 1906, Biscayne Park', + 'zip': 'FL33137', + 'city': 'Miami', + 'country': country.id, + 'subdivision': subdivision.id, + 'phone': '12345678' + } + ) + self.assertTrue( + rv.location.endswith('/checkout/shipping-address') + ) + + self.assertEqual(address.phone_number.value, '12345678') + + self.assertEqual(rv.status_code, 302) + class TestCheckoutDeliveryMethod(BaseTestCheckout): "Test the Delivery Method Step"