Add historical amounts to new purchase Order Form, allow extra columns etc.
This commit is contained in:
		
							parent
							
								
									bf5808d517
								
							
						
					
					
						commit
						da5c040aeb
					
				
					 2 changed files with 65 additions and 21 deletions
				
			
		| 
						 | 
				
			
			@ -61,7 +61,8 @@
 | 
			
		|||
    .order-form td.upc,
 | 
			
		||||
    .order-form td.case-qty,
 | 
			
		||||
    .order-form td.code,
 | 
			
		||||
    .order-form td.preferred {
 | 
			
		||||
    .order-form td.preferred,
 | 
			
		||||
    .order-form td.scratch_pad {
 | 
			
		||||
        text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,11 +101,6 @@
 | 
			
		|||
    <div class="field">${vendor}</div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="field-wrapper">
 | 
			
		||||
    <label>Order Date</label>
 | 
			
		||||
    <div class="field">${batch.date_ordered}</div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="field-wrapper po-total">
 | 
			
		||||
    <label>PO Total</label>
 | 
			
		||||
    <div class="field">$${'{:0,.2f}'.format(batch.po_total or 0)}</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -115,14 +111,15 @@
 | 
			
		|||
 | 
			
		||||
<div class="newgrid">
 | 
			
		||||
  <table class="order-form">
 | 
			
		||||
    <% column_count = 22 + int(capture(self.extra_count)) %>
 | 
			
		||||
    % for department in sorted(departments.itervalues(), key=lambda d: d.name if d else ''):
 | 
			
		||||
        <thead>
 | 
			
		||||
          <tr>
 | 
			
		||||
            <th class="department" colspan="22">Department:  ${department.number} ${department.name}</th>
 | 
			
		||||
            <th class="department" colspan="${column_count}">Department ${department.number} ${department.name}</th>
 | 
			
		||||
          </tr>
 | 
			
		||||
          % for subdepartment in sorted(department._order_subdepartments.itervalues(), key=lambda s: s.name if s else ''):
 | 
			
		||||
              <tr>
 | 
			
		||||
                <th class="subdepartment" colspan="22">Subdepartment:  ${subdepartment.number} ${subdepartment.name}</th>
 | 
			
		||||
                <th class="subdepartment" colspan="${column_count}">Subdepartment ${subdepartment.number} ${subdepartment.name}</th>
 | 
			
		||||
              </tr>
 | 
			
		||||
              <tr>
 | 
			
		||||
                <th>UPC</th>
 | 
			
		||||
| 
						 | 
				
			
			@ -132,8 +129,12 @@
 | 
			
		|||
                <th>Vend. Code</th>
 | 
			
		||||
                <th>Pref.</th>
 | 
			
		||||
                <th>Unit Cost</th>
 | 
			
		||||
                <th colspan="7"> </th>
 | 
			
		||||
                % for data in history.itervalues():
 | 
			
		||||
                    <th>${data['purchase'].date_ordered.strftime('%m/%d') if data else ''}</th>
 | 
			
		||||
                % endfor
 | 
			
		||||
                <th>${batch.date_ordered.strftime('%m/%d')}</th>
 | 
			
		||||
                <th>PO Total</th>
 | 
			
		||||
                ${self.extra_th()}
 | 
			
		||||
              </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
| 
						 | 
				
			
			@ -146,13 +147,18 @@
 | 
			
		|||
                    <td class="code">${cost.code or ''}</td>
 | 
			
		||||
                    <td class="preferred">${'X' if cost.preference == 1 else ''}</td>
 | 
			
		||||
                    <td class="unit-cost">$${'{:0.2f}'.format(cost.unit_cost)}</td>
 | 
			
		||||
                    % for i in range(6):
 | 
			
		||||
                        <td class="scratch_pad">        </td>
 | 
			
		||||
                    % for data in history.itervalues():
 | 
			
		||||
                        <td class="scratch_pad">
 | 
			
		||||
                          % if data and cost.product_uuid in data['items']:
 | 
			
		||||
                              ${int(data['items'][cost.product_uuid].cases_ordered or 0) or ''}
 | 
			
		||||
                          % endif
 | 
			
		||||
                        </td>
 | 
			
		||||
                    % endfor
 | 
			
		||||
                    <td class="current-order">
 | 
			
		||||
                       ${h.text('cases_ordered_{}'.format(cost.uuid), value=int(cost._batchrow.cases_ordered) if cost._batchrow else None)}
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td class="po-total">${'${:0,.2f}'.format(cost._batchrow.po_total) if cost._batchrow else ''}</td>
 | 
			
		||||
                    ${self.extra_td(cost)}
 | 
			
		||||
                  </tr>
 | 
			
		||||
              % endfor
 | 
			
		||||
            </tbody>
 | 
			
		||||
| 
						 | 
				
			
			@ -160,3 +166,10 @@
 | 
			
		|||
    % endfor
 | 
			
		||||
  </table>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<%def name="extra_count()">0</%def>
 | 
			
		||||
 | 
			
		||||
<%def name="extra_th()"></%def>
 | 
			
		||||
 | 
			
		||||
<%def name="extra_td(cost)"></%def>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,11 +26,15 @@ Views for purchase order batches
 | 
			
		|||
 | 
			
		||||
from __future__ import unicode_literals, absolute_import
 | 
			
		||||
 | 
			
		||||
from sqlalchemy import orm
 | 
			
		||||
 | 
			
		||||
from rattail import enum
 | 
			
		||||
from rattail.db import model, api
 | 
			
		||||
from rattail.gpc import GPC
 | 
			
		||||
from rattail.db.batch.purchase.handler import PurchaseBatchHandler
 | 
			
		||||
from rattail.time import localtime
 | 
			
		||||
from rattail.core import Object
 | 
			
		||||
from rattail.util import OrderedDict
 | 
			
		||||
 | 
			
		||||
import formalchemy as fa
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -271,14 +275,6 @@ class PurchaseBatchView(BatchMasterView):
 | 
			
		|||
        batch = self.get_instance()
 | 
			
		||||
        if batch.executed:
 | 
			
		||||
            return self.redirect(self.get_action_url('view', batch))
 | 
			
		||||
        vendor = batch.vendor
 | 
			
		||||
        costs = Session.query(model.ProductCost)\
 | 
			
		||||
                       .join(model.Product)\
 | 
			
		||||
                       .outerjoin(model.Brand)\
 | 
			
		||||
                       .filter(model.ProductCost.vendor == vendor)\
 | 
			
		||||
                       .order_by(model.Brand.name,
 | 
			
		||||
                                 model.Product.description,
 | 
			
		||||
                                 model.Product.size)
 | 
			
		||||
 | 
			
		||||
        # organize existing batch rows by product
 | 
			
		||||
        order_items = {}
 | 
			
		||||
| 
						 | 
				
			
			@ -286,8 +282,12 @@ class PurchaseBatchView(BatchMasterView):
 | 
			
		|||
            if not row.removed:
 | 
			
		||||
                order_items[row.product_uuid] = row
 | 
			
		||||
 | 
			
		||||
        # organize product costs by dept / subdept
 | 
			
		||||
        # organize vendor catalog costs by dept / subdept
 | 
			
		||||
        departments = {}
 | 
			
		||||
        costs = self.get_order_form_costs(batch.vendor)\
 | 
			
		||||
                    .order_by(model.Brand.name,
 | 
			
		||||
                              model.Product.description,
 | 
			
		||||
                              model.Product.size)
 | 
			
		||||
        for cost in costs:
 | 
			
		||||
 | 
			
		||||
            department = cost.product.department
 | 
			
		||||
| 
						 | 
				
			
			@ -318,6 +318,27 @@ class PurchaseBatchView(BatchMasterView):
 | 
			
		|||
            subdept_costs.append(cost)
 | 
			
		||||
            cost._batchrow = order_items.get(cost.product_uuid)
 | 
			
		||||
 | 
			
		||||
            # do anything else needed to satisfy template display requirements etc.
 | 
			
		||||
            self.decorate_order_form_cost(cost)
 | 
			
		||||
 | 
			
		||||
        # fetch last 6 purchases for this vendor, organize line items by product
 | 
			
		||||
        history = OrderedDict()
 | 
			
		||||
        purchases = Session.query(model.Purchase)\
 | 
			
		||||
                           .filter(model.Purchase.vendor == batch.vendor)\
 | 
			
		||||
                           .filter(model.Purchase.status >= enum.PURCHASE_STATUS_ORDERED)\
 | 
			
		||||
                           .order_by(model.Purchase.date_ordered.desc(), model.Purchase.created.desc())\
 | 
			
		||||
                           .options(orm.joinedload(model.Purchase.items))[:6]
 | 
			
		||||
        for purchase in purchases[:6]:
 | 
			
		||||
            items = {}
 | 
			
		||||
            for item in purchase.items:
 | 
			
		||||
                items[item.product_uuid] = item
 | 
			
		||||
            history[purchase.uuid] = {'purchase': purchase, 'items': items}
 | 
			
		||||
 | 
			
		||||
        # reverse sorting and pad history as needed, for template convenience
 | 
			
		||||
        for i in range(6 - len(history)):
 | 
			
		||||
            history[i] = None
 | 
			
		||||
        history = OrderedDict([(i, v) for i, v in enumerate(reversed(list(history.itervalues())))])
 | 
			
		||||
 | 
			
		||||
        title = self.get_instance_title(batch)
 | 
			
		||||
        return self.render_to_response('order_form', {
 | 
			
		||||
            'batch': batch,
 | 
			
		||||
| 
						 | 
				
			
			@ -325,11 +346,21 @@ class PurchaseBatchView(BatchMasterView):
 | 
			
		|||
            'instance_title': title,
 | 
			
		||||
            'index_title': "{}: {}".format(self.get_model_title(), title),
 | 
			
		||||
            'index_url': self.get_action_url('view', batch),
 | 
			
		||||
            'vendor': vendor,
 | 
			
		||||
            'vendor': batch.vendor,
 | 
			
		||||
            'departments': departments,
 | 
			
		||||
            'history': history,
 | 
			
		||||
            'get_upc': lambda p: p.upc.pretty() if p.upc else '',
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
    def get_order_form_costs(self, vendor):
 | 
			
		||||
        return Session.query(model.ProductCost)\
 | 
			
		||||
                      .join(model.Product)\
 | 
			
		||||
                      .outerjoin(model.Brand)\
 | 
			
		||||
                      .filter(model.ProductCost.vendor == vendor)
 | 
			
		||||
 | 
			
		||||
    def decorate_order_form_cost(self, cost):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def order_form_update(self):
 | 
			
		||||
        """
 | 
			
		||||
        Handles AJAX requests to update current batch, from Order Form view.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue