Changeset 808e737 in tailbone


Ignore:
Timestamp:
08/02/2020 08:59:16 PM (3 years ago)
Author:
Lance Edgar <lance@…>
Branches:
master
Children:
7d158e5
Parents:
c32f47b
Message:

Add basic/unfinished "new customer order" page/feature

so far creates the order batch, and can set some customer info

Location:
tailbone
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • tailbone/views/custorders/batch.py

    rc32f47b r808e737  
    2727from __future__ import unicode_literals, absolute_import
    2828
     29import six
     30
    2931from rattail.db import model
    3032
     33import colander
     34
     35from tailbone import forms
    3136from tailbone.views.batch import BatchMasterView
    3237
     
    4045    model_row_class = model.CustomerOrderBatchRow
    4146    default_handler_spec = 'rattail.batch.custorder:CustomerOrderBatchHandler'
     47
     48    grid_columns = [
     49        'id',
     50        'customer',
     51        'rows',
     52        'created',
     53        'created_by',
     54    ]
     55
     56    form_fields = [
     57        'id',
     58        'customer',
     59        'person',
     60        'phone_number',
     61        'email_address',
     62        'created',
     63        'created_by',
     64        'rows',
     65        'status_code',
     66    ]
     67
     68    def configure_grid(self, g):
     69        super(CustomerOrderBatchView, self).configure_grid(g)
     70
     71        g.set_link('customer')
     72        g.set_link('created')
     73        g.set_link('created_by')
     74
     75    def configure_form(self, f):
     76        super(CustomerOrderBatchView, self).configure_form(f)
     77        order = f.model_instance
     78        model = self.rattail_config.get_model()
     79
     80        # readonly fields
     81        f.set_readonly('rows')
     82        f.set_readonly('status_code')
     83
     84        # customer
     85        if 'customer' in f.fields and self.editing:
     86            f.replace('customer', 'customer_uuid')
     87            f.set_node('customer_uuid', colander.String(), missing=colander.null)
     88            customer_display = ""
     89            if self.request.method == 'POST':
     90                if self.request.POST.get('customer_uuid'):
     91                    customer = self.Session.query(model.Customer)\
     92                                           .get(self.request.POST['customer_uuid'])
     93                    if customer:
     94                        customer_display = six.text_type(customer)
     95            elif self.editing:
     96                customer_display = six.text_type(order.customer or "")
     97            customers_url = self.request.route_url('customers.autocomplete')
     98            f.set_widget('customer_uuid', forms.widgets.JQueryAutocompleteWidget(
     99                field_display=customer_display, service_url=customers_url))
     100            f.set_label('customer_uuid', "Customer")
     101        else:
     102            f.set_renderer('customer', self.render_customer)
     103
     104        # person
     105        if 'person' in f.fields and self.editing:
     106            f.replace('person', 'person_uuid')
     107            f.set_node('person_uuid', colander.String(), missing=colander.null)
     108            person_display = ""
     109            if self.request.method == 'POST':
     110                if self.request.POST.get('person_uuid'):
     111                    person = self.Session.query(model.Person)\
     112                                         .get(self.request.POST['person_uuid'])
     113                    if person:
     114                        person_display = six.text_type(person)
     115            elif self.editing:
     116                person_display = six.text_type(order.person or "")
     117            people_url = self.request.route_url('people.autocomplete')
     118            f.set_widget('person_uuid', forms.widgets.JQueryAutocompleteWidget(
     119                field_display=person_display, service_url=people_url))
     120            f.set_label('person_uuid', "Person")
     121        else:
     122            f.set_renderer('person', self.render_person)
  • tailbone/views/custorders/creating.py

    rc32f47b r808e737  
    2323"""
    2424Views for 'creating' customer order batches
     25
     26Note that this provides only the "direct" or "raw" table views for these
     27batches.  This does *not* provide a way to create a new batch; you should see
     28:meth:`tailbone.views.custorders.orders.CustomerOrdersView.create()` for that
     29logic.
    2530"""
    2631
  • tailbone/views/custorders/orders.py

    rc32f47b r808e737  
    33#
    44#  Rattail -- Retail Software Framework
    5 #  Copyright © 2010-2018 Lance Edgar
     5#  Copyright © 2010-2020 Lance Edgar
    66#
    77#  This file is part of Rattail.
     
    4444    model_class = model.CustomerOrder
    4545    route_prefix = 'custorders'
    46     creatable = False
    4746    editable = False
    4847    deletable = False
     
    6059        'customer',
    6160        'person',
     61        'phone_number',
     62        'email_address',
    6263        'created',
    6364        'status_code',
     
    116117        return tags.link_to(text, url)
    117118
     119    def create(self, form=None, template='create'):
     120        """
     121        View for creating a new customer order.  Note that it does so by way of
     122        maintaining a "new customer order" batch, until the user finally
     123        submits the order, at which point the batch is converted to a proper
     124        order.
     125        """
     126        batch = self.get_current_batch()
     127
     128        if self.request.method == 'POST':
     129
     130            # first we check for traditional form post
     131            action = self.request.POST.get('action')
     132            post_actions = [
     133                'start_over_entirely',
     134                'delete_batch',
     135            ]
     136            if action in post_actions:
     137                return getattr(self, action)(batch)
     138
     139            # okay then, we'll assume newer JSON-style post params
     140            data = dict(self.request.json_body)
     141            action = data.get('action')
     142            json_actions = [
     143                'get_customer_info',
     144                'set_customer_data',
     145                'submit_new_order',
     146            ]
     147            if action in json_actions:
     148                result = getattr(self, action)(batch, data)
     149                return self.json_response(result)
     150
     151        context = {'batch': batch}
     152        return self.render_to_response(template, context)
     153
     154    def get_current_batch(self):
     155        user = self.request.user
     156        if not user:
     157            raise RuntimeError("this feature requires a user to be logged in")
     158
     159        try:
     160            # there should be at most *one* new batch per user
     161            batch = self.Session.query(model.CustomerOrderBatch)\
     162                                .filter(model.CustomerOrderBatch.mode == self.enum.CUSTORDER_BATCH_MODE_CREATING)\
     163                                .filter(model.CustomerOrderBatch.created_by == user)\
     164                                .one()
     165
     166        except orm.exc.NoResultFound:
     167            # no batch yet for this user, so make one
     168            batch = model.CustomerOrderBatch()
     169            batch.mode = self.enum.CUSTORDER_BATCH_MODE_CREATING
     170            batch.created_by = user
     171            self.Session.add(batch)
     172            self.Session.flush()
     173
     174        return batch
     175
     176    def start_over_entirely(self, batch):
     177        # just delete current batch outright
     178        # TODO: should use self.handler.do_delete() instead?
     179        self.Session.delete(batch)
     180        self.Session.flush()
     181
     182        # send user back to normal "create" page; a new batch will be generated
     183        # for them automatically
     184        route_prefix = self.get_route_prefix()
     185        url = self.request.route_url('{}.create'.format(route_prefix))
     186        return self.redirect(url)
     187
     188    def delete_batch(self, batch):
     189        # just delete current batch outright
     190        # TODO: should use self.handler.do_delete() instead?
     191        self.Session.delete(batch)
     192        self.Session.flush()
     193
     194        # set flash msg just to be more obvious
     195        self.request.session.flash("New customer order has been deleted.")
     196
     197        # send user back to customer orders page, w/ no new batch generated
     198        route_prefix = self.get_route_prefix()
     199        url = self.request.route_url(route_prefix)
     200        return self.redirect(url)
     201
     202    def get_customer_info(self, batch, data):
     203        uuid = data.get('uuid')
     204        if not uuid:
     205            return {'error': "Must specify a customer UUID"}
     206
     207        customer = self.Session.query(model.Customer).get(uuid)
     208        if not customer:
     209            return {'error': "Customer not found"}
     210
     211        return self.info_for_customer(batch, data, customer)
     212
     213    def info_for_customer(self, batch, data, customer):
     214        phone = customer.first_phone()
     215        email = customer.first_email()
     216        return {
     217            'uuid': customer.uuid,
     218            'phone_number': phone.number if phone else None,
     219            'email_address': email.address if email else None,
     220        }
     221
     222    def set_customer_data(self, batch, data):
     223        if 'customer_uuid' in data:
     224            batch.customer_uuid = data['customer_uuid']
     225            if 'person_uuid' in data:
     226                batch.person_uuid = data['person_uuid']
     227            elif batch.customer_uuid:
     228                self.Session.flush()
     229                batch.person = batch.customer.first_person()
     230            else: # no customer set
     231                batch.person_uuid = None
     232        if 'phone_number' in data:
     233            batch.phone_number = data['phone_number']
     234        if 'email_address' in data:
     235            batch.email_address = data['email_address']
     236        self.Session.flush()
     237        return {'success': True}
     238
     239    def submit_new_order(self, batch, data):
     240        # TODO
     241        return {'success': True}
     242
    118243
    119244def includeme(config):
Note: See TracChangeset for help on using the changeset viewer.