source: tailbone/tailbone/views/purchases/credits.py @ 3760c32

Last change on this file since 3760c32 was 3760c32, checked in by Lance Edgar <ledgar@…>, 9 months ago

Improve display of purchase credit data

esp. within a receiving batch row

  • Property mode set to 100644
File size: 6.3 KB
Line 
1# -*- coding: utf-8; -*-
2################################################################################
3#
4#  Rattail -- Retail Software Framework
5#  Copyright © 2010-2019 Lance Edgar
6#
7#  This file is part of Rattail.
8#
9#  Rattail is free software: you can redistribute it and/or modify it under the
10#  terms of the GNU General Public License as published by the Free Software
11#  Foundation, either version 3 of the License, or (at your option) any later
12#  version.
13#
14#  Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
15#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16#  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17#  details.
18#
19#  You should have received a copy of the GNU General Public License along with
20#  Rattail.  If not, see <http://www.gnu.org/licenses/>.
21#
22################################################################################
23"""
24Views for "true" purchase credits
25"""
26
27from __future__ import unicode_literals, absolute_import
28
29import six
30
31from rattail.db import model
32
33from webhelpers2.html import tags
34
35from tailbone import grids
36from tailbone.views import MasterView
37
38
39class PurchaseCreditView(MasterView):
40    """
41    Master view for purchase credits
42    """
43    model_class = model.PurchaseCredit
44    route_prefix = 'purchases.credits'
45    url_prefix = '/purchases/credits'
46    creatable = False
47    editable = False
48    checkboxes = True
49
50    labels = {
51        'upc': "UPC",
52        'mispick_upc': "Mispick UPC",
53    }
54
55    grid_columns = [
56        'vendor',
57        'invoice_number',
58        'invoice_date',
59        'upc',
60        'vendor_item_code',
61        'brand_name',
62        'description',
63        'size',
64        'cases_shorted',
65        'units_shorted',
66        'credit_total',
67        'credit_type',
68        'mispick_upc',
69        'date_received',
70        'status',
71    ]
72
73    form_fields = [
74        'store',
75        'vendor',
76        'invoice_number',
77        'invoice_date',
78        'date_ordered',
79        'date_shipped',
80        'date_received',
81        'department_number',
82        'department_name',
83        'vendor_item_code',
84        'upc',
85        'product',
86        'case_quantity',
87        'credit_type',
88        'cases_shorted',
89        'units_shorted',
90        'invoice_line_number',
91        'invoice_case_cost',
92        'invoice_unit_cost',
93        'invoice_total',
94        'credit_total',
95        'mispick_upc',
96        'mispick_product',
97        'product_discarded',
98        'expiration_date',
99        'status',
100    ]
101
102    def configure_grid(self, g):
103        super(PurchaseCreditView, self).configure_grid(g)
104
105        g.set_joiner('vendor', lambda q: q.outerjoin(model.Vendor))
106        g.set_sorter('vendor', model.Vendor.name)
107
108        g.set_sort_defaults('date_received', 'desc')
109
110        g.set_enum('status', self.enum.PURCHASE_CREDIT_STATUS)
111        g.filters['status'].set_value_renderer(grids.filters.EnumValueRenderer(self.enum.PURCHASE_CREDIT_STATUS))
112        g.filters['status'].default_active = True
113        g.filters['status'].default_verb = 'not_equal'
114        # TODO: should not have to convert value to string!
115        g.filters['status'].default_value = six.text_type(self.enum.PURCHASE_CREDIT_STATUS_SATISFIED)
116
117        # g.set_type('upc', 'gpc')
118        g.set_type('cases_shorted', 'quantity')
119        g.set_type('units_shorted', 'quantity')
120        g.set_type('credit_total', 'currency')
121
122        g.set_label('invoice_number', "Invoice No.")
123        g.set_label('vendor_item_code', "Item Code")
124        g.set_label('brand_name', "Brand")
125        g.set_label('cases_shorted', "Cases")
126        g.set_label('units_shorted', "Units")
127        g.set_label('credit_type', "Type")
128        g.set_label('date_received', "Date")
129
130        g.set_link('upc')
131        g.set_link('vendor_item_code')
132        g.set_link('brand_name')
133        g.set_link('description')
134
135    def configure_form(self, f):
136        super(PurchaseCreditView, self).configure_form(f)
137
138        # status
139        f.set_enum('status', self.enum.PURCHASE_CREDIT_STATUS)
140
141    def change_status(self):
142        if self.request.method != 'POST':
143            self.request.session.flash("Sorry, you must POST to change credit status", 'error')
144            return self.redirect(self.get_index_url())
145
146        status = self.request.POST.get('status', '')
147        if status.isdigit():
148            status = int(status)
149        else:
150            self.request.session.flash("Received invalid status: {}".format(status), 'error')
151            return self.redirect(self.get_index_url())
152
153        credits_ = []
154        for uuid in self.request.POST.get('uuids', '').split(','):
155            uuid = uuid.strip()
156            if uuid:
157                credit = self.Session.query(model.PurchaseCredit).get(uuid)
158                if credit:
159                    credits_.append(credit)
160        if not credits_:
161            self.request.session.flash("Received zero valid credits", 'error')
162            return self.redirect(self.get_index_url())
163
164        # okay, really change status
165        for credit in credits_:
166            credit.status = status
167
168        self.request.session.flash("Changed status for {} credits".format(len(credits_)))
169        return self.redirect(self.get_index_url())
170
171    def template_kwargs_index(self, **kwargs):
172        kwargs['status_options'] = self.status_options()
173        return kwargs
174
175    def status_options(self):
176        options = []
177        for value in sorted(self.enum.PURCHASE_CREDIT_STATUS):
178            options.append(tags.Option(self.enum.PURCHASE_CREDIT_STATUS[value], value))
179        return options
180
181    @classmethod
182    def defaults(cls, config):
183        route_prefix = cls.get_route_prefix()
184        url_prefix = cls.get_url_prefix()
185        permission_prefix = cls.get_permission_prefix()
186        model_title_plural = cls.get_model_title_plural()
187
188        # change status
189        config.add_tailbone_permission(permission_prefix, '{}.change_status'.format(permission_prefix),
190                                       "Change status for {}".format(model_title_plural))
191        config.add_route('{}.change_status'.format(route_prefix), '{}/change-status'.format(url_prefix))
192        config.add_view(cls, attr='change_status', route_name='{}.change_status'.format(route_prefix),
193                        permission='{}.change_status'.format(permission_prefix))
194
195        cls._defaults(config)
196
197
198def includeme(config):
199    PurchaseCreditView.defaults(config)
Note: See TracBrowser for help on using the repository browser.