Example #1
0
class DetailReport(GridReport):
  '''
  A list report to show operationplans.
  '''
  template = 'output/operationplan.html'
  title = _("Operation detail report")
  model = OperationPlan
  permissions = (("view_operation_report", "Can view operation report"),)
  frozenColumns = 0
  editable = False
  multiselect = False

  @ classmethod
  def basequeryset(reportclass, request, args, kwargs):
    if args and args[0]:
      return OperationPlan.objects.filter(operation__exact=args[0]).extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",})
    else:
      return OperationPlan.objects.extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",})

  @classmethod
  def extra_context(reportclass, request, *args, **kwargs):
    return {'active_tab': 'plandetail'}

  rows = (
    GridFieldInteger('id', title=_('operationplan'), key=True, editable=False),
    GridFieldText('operation', title=_('operation'), formatter='operation', editable=False),
    GridFieldNumber('quantity', title=_('quantity'), editable=False),
    GridFieldDateTime('startdate', title=_('start date'), editable=False),
    GridFieldDateTime('enddate', title=_('end date'), editable=False),
    GridFieldBool('locked', title=_('locked'), editable=False),
    GridFieldNumber('unavailable', title=_('unavailable'), editable=False),
    GridFieldInteger('owner', title=_('owner'), editable=False),
    )
Example #2
0
class DetailReport(GridReport):
  '''
  A list report to show flowplans.
  '''
  template = 'output/flowplan.html'
  title = _("Inventory detail report")
  model = FlowPlan
  permissions = (('view_inventory_report','Can view inventory report'),)
  frozenColumns = 0
  editable = False
  multiselect = False

  @ classmethod
  def basequeryset(reportclass, request, args, kwargs):
    if args and args[0]:
      return FlowPlan.objects.filter(thebuffer__exact=args[0]).extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",})
    else:
      return FlowPlan.objects.extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",})

  @classmethod
  def extra_context(reportclass, request, *args, **kwargs):
    return {'active_tab': 'plandetail'}

  rows = (
    GridFieldText('thebuffer', title=_('buffer'), key=True, formatter='buffer', editable=False),
    GridFieldText('operationplan__operation', title=_('operation'), formatter='operation', editable=False),
    GridFieldNumber('quantity', title=_('quantity'), editable=False),
    GridFieldDateTime('flowdate', title=_('date'), editable=False),
    GridFieldNumber('onhand', title=_('onhand'), editable=False),
    GridFieldBool('operationplan__locked', title=_('locked'), editable=False),
    GridFieldInteger('operationplan', title=_('operationplan'), editable=False),
    )
Example #3
0
class OperationList(GridReport):
    '''
  A list report to show operations.
  '''
    template = 'input/operationlist.html'
    title = _("Operation List")
    basequeryset = Operation.objects.all()
    model = Operation
    frozenColumns = 1

    rows = (
        GridFieldText('name', title=_('name'), key=True,
                      formatter='operation'),
        GridFieldText('description', title=_('description')),
        GridFieldText('category', title=_('category')),
        GridFieldText('subcategory', title=_('subcategory')),
        GridFieldChoice('type', title=_('type'), choices=Operation.types),
        GridFieldText('location',
                      title=_('location'),
                      field_name='location__name',
                      formatter='location'),
        GridFieldDuration('duration', title=_('duration')),
        GridFieldDuration('duration_per', title=_('duration per unit')),
        GridFieldDuration('fence', title=_('release fence')),
        GridFieldDuration('posttime', title=_('post-op time')),
        GridFieldNumber('sizeminimum', title=_('size minimum')),
        GridFieldNumber('sizemultiple', title=_('size multiple')),
        GridFieldNumber('sizemaximum', title=_('size maximum')),
        GridFieldCurrency('cost', title=_('cost')),
        GridFieldChoice('search', title=_('search mode'), choices=searchmode),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #4
0
class ItemDistributionList(GridReport):
    '''
  A list report to show item distribution.
  '''
    template = 'input/itemdistributionlist.html'
    title = _("Item Distribution List")
    basequeryset = ItemDistribution.objects.all()
    model = ItemDistribution
    frozenColumns = 1

    rows = (
        GridFieldInteger('id',
                         title=_('identifier'),
                         key=True,
                         formatter='itemdistribution'),
        GridFieldText('item', title=_('item'), formatter='item'),
        GridFieldText('location', title=_('location'), formatter='location'),
        GridFieldText('origin', title=_('origin'), formatter='location'),
        GridFieldDuration('leadtime', title=_('lead time')),
        GridFieldNumber('sizeminimum', title=_('size minimum')),
        GridFieldNumber('sizemultiple', title=_('size multiple')),
        GridFieldCurrency('cost', title=_('cost')),
        GridFieldNumber('priority', title=_('priority')),
        GridFieldDateTime('effective_start', title=_('effective start')),
        GridFieldDateTime('effective_end', title=_('effective end')),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #5
0
class PurchaseOrderList(GridReport):
    '''
  A list report to show purchase orders.
  '''
    template = 'input/purchaseorderlist.html'
    title = _("Purchase order List")
    basequeryset = PurchaseOrder.objects.all()
    model = PurchaseOrder
    frozenColumns = 1

    rows = (
        GridFieldInteger('id', title=_('identifier'), key=True),
        GridFieldText('reference', title=_('reference')),
        GridFieldChoice('status',
                        title=_('status'),
                        choices=PurchaseOrder.orderstatus),
        GridFieldText('item',
                      title=_('item'),
                      field_name='item__name',
                      formatter='item'),
        GridFieldText('supplier',
                      title=_('supplier'),
                      field_name='supplier__name',
                      formatter='supplier'),
        GridFieldDateTime('startdate', title=_('start date')),
        GridFieldDateTime('enddate', title=_('end date')),
        GridFieldNumber('quantity', title=_('quantity')),
        GridFieldNumber('criticality', title=_('criticality'), editable=False),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #6
0
class DetailReport(GridReport):
  '''
  A list report to show delivery plans for demand.
  '''
  template = 'output/demandplan.html'
  title = _("Demand plan detail")
  model = Demand
  permissions = (("view_demand_report", "Can view demand report"),)
  frozenColumns = 0
  editable = False
  multiselect = False

  @ classmethod
  def basequeryset(reportclass, request, args, kwargs):
    if args and args[0]:
      return Demand.objects.filter(item__exact=args[0])
    else:
      return Demand.objects.all()

  @classmethod
  def extra_context(reportclass, request, *args, **kwargs):
    return {'active_tab': 'plandetail'}

  rows = (
    GridFieldText('demand', title=_('demand'), key=True, editable=False, formatter='demand'),
    GridFieldText('item', title=_('item'), formatter='item', editable=False),
    GridFieldText('customer', title=_('customer'), formatter='customer', editable=False),
    GridFieldNumber('quantity', title=_('quantity'), editable=False),
    GridFieldNumber('planquantity', title=_('planned quantity'), editable=False),
    GridFieldDateTime('due', title=_('due date'), editable=False),
    GridFieldDateTime('plandate', title=_('planned date'), editable=False),
    GridFieldInteger('operationplan', title=_('operationplan'), editable=False),
    )
Example #7
0
class LoadList(GridReport):
    '''
  A list report to show loads.
  '''
    template = 'input/loadlist.html'
    title = _("Load List")
    basequeryset = Load.objects.all()
    model = Load
    frozenColumns = 1

    rows = (
        GridFieldInteger('id',
                         title=_('identifier'),
                         key=True,
                         formatter='load'),
        GridFieldText('operation',
                      title=_('operation'),
                      field_name='operation__name',
                      formatter='operation'),
        GridFieldText('resource',
                      title=_('resource'),
                      field_name='resource__name',
                      formatter='resource'),
        GridFieldText('skill', title=_('skill'), formatter='skill'),
        GridFieldNumber('quantity', title=_('quantity')),
        GridFieldDateTime('effective_start', title=_('effective start')),
        GridFieldDateTime('effective_end', title=_('effective end')),
        GridFieldText('name', title=_('name')),
        GridFieldText('alternate', title=_('alternate')),
        GridFieldNumber('priority', title=_('priority')),
        GridFieldText('setup', title=_('setup')),
        GridFieldChoice('search', title=_('search mode'), choices=searchmode),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #8
0
class FlowList(GridReport):
    '''
  A list report to show flows.
  '''
    template = 'input/flowlist.html'
    title = _("Flow List")
    basequeryset = Flow.objects.all()
    model = Flow
    frozenColumns = 1

    rows = (
        GridFieldInteger('id',
                         title=_('identifier'),
                         key=True,
                         formatter='flow'),
        GridFieldText('operation',
                      title=_('operation'),
                      field_name='operation__name',
                      formatter='operation'),
        GridFieldText('thebuffer',
                      title=_('buffer'),
                      field_name='thebuffer__name',
                      formatter='buffer'),
        GridFieldChoice('type', title=_('type'), choices=Flow.types),
        GridFieldNumber('quantity', title=_('quantity')),
        GridFieldDateTime('effective_start', title=_('effective start')),
        GridFieldDateTime('effective_end', title=_('effective end')),
        GridFieldText('name', title=_('name')),
        GridFieldText('alternate', title=_('alternate')),
        GridFieldNumber('priority', title=_('priority')),
        GridFieldChoice('search', title=_('search mode'), choices=searchmode),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #9
0
class DetailReport(GridReport):
    '''
  A list report to show operationplans.
  '''
    template = 'output/operationplan.html'
    title = _("Operation detail report")
    model = OperationPlan
    permissions = (("view_operation_report", "Can view operation report"), )
    frozenColumns = 0
    editable = False
    multiselect = False

    @classmethod
    def basequeryset(reportclass, request, args, kwargs):
        if args and args[0]:
            base = OperationPlan.objects.filter(operation__exact=args[0])
        else:
            base = OperationPlan.objects
        return base.select_related() \
          .extra(select={
            'operation_in': "select name from operation where out_operationplan.operation = operation.name",
            'demand': ("select %s(q || ' : ' || d, ', ') from ("
                       "select round(sum(quantity)) as q, demand as d "
                       "from out_demandpegging "
                       "where out_demandpegging.operationplan = out_operationplan.id "
                       "group by demand order by 1 desc, 2) peg"
                       % string_agg())
            })

    @classmethod
    def extra_context(reportclass, request, *args, **kwargs):
        if args and args[0]:
            request.session['lasttab'] = 'plandetail'
        return {'active_tab': 'plandetail'}

    rows = (
        GridFieldInteger('id',
                         title=_('operationplan'),
                         key=True,
                         editable=False),
        GridFieldText('operation',
                      title=_('operation'),
                      editable=False,
                      formatter='detail',
                      extra="role:'input/operation'"),
        GridFieldNumber('quantity', title=_('quantity'), editable=False),
        GridFieldText('demand',
                      title=_('demand quantity'),
                      formatter='demanddetail',
                      extra="role:'input/demand'",
                      width=300,
                      editable=False),
        GridFieldDateTime('startdate', title=_('start date'), editable=False),
        GridFieldDateTime('enddate', title=_('end date'), editable=False),
        GridFieldNumber('criticality', title=_('criticality'), editable=False),
        GridFieldBool('locked', title=_('locked'), editable=False),
        GridFieldNumber('unavailable', title=_('unavailable'), editable=False),
        GridFieldInteger('owner', title=_('owner'), editable=False),
    )
Example #10
0
class ItemList(GridReport):
    title = _("items")
    basequeryset = Item.objects.all()
    model = Item
    frozenColumns = 1
    editable = True
    help_url = "modeling-wizard/master-data/items.html"
    message_when_empty = Template("""
        <h3>Define items</h3>
        <br>
        A basic piece of master data is the list of items to plan.<br>
        End products, intermediate products and raw materials all need to be defined.<br>
        <br><br>
        <div role="group" class="btn-group.btn-group-justified">
        <a href="{{request.prefix}}/data/input/item/add/" class="btn btn-primary">Create a single item<br>in a form</a>
        <a href="{{request.prefix}}/wizard/load/production/?currentstep=1" class="btn btn-primary">Wizard to upload items<br>from a spreadsheet</a>
        </div>
        <br>
        """)

    rows = (
        GridFieldHierarchicalText(
            "name",
            title=_("name"),
            key=True,
            formatter="detail",
            extra='"role":"input/item"',
            model=Item,
        ),
        GridFieldText("description", title=_("description")),
        GridFieldText("category", title=_("category"), initially_hidden=True),
        GridFieldText("subcategory",
                      title=_("subcategory"),
                      initially_hidden=True),
        GridFieldText(
            "owner",
            title=_("owner"),
            field_name="owner__name",
            formatter="detail",
            extra='"role":"input/item"',
        ),
        GridFieldCurrency("cost", title=_("cost")),
        GridFieldNumber("weight", title=_("weight"), initially_hidden=True),
        GridFieldNumber("volume", title=_("volume"), initially_hidden=True),
        GridFieldText("uom", title=_("unit of measure"),
                      initially_hidden=True),
        GridFieldInteger("periodofcover",
                         title=_("period of cover"),
                         initially_hidden=True),
        GridFieldChoice("type",
                        title=_("type"),
                        choices=Item.types,
                        initially_hidden=True),
        GridFieldText("source", title=_("source"), initially_hidden=True),
        GridFieldLastModified("lastmodified"),
    )
Example #11
0
class DetailReport(GridReport):
    '''
  A list report to show loadplans.
  '''
    template = 'output/loadplan.html'
    title = _("Resource detail report")
    model = LoadPlan
    permissions = (("view_resource_report", "Can view resource report"), )
    frozenColumns = 0
    editable = False
    multiselect = False

    @classmethod
    def basequeryset(reportclass, request, args, kwargs):
        if args and args[0]:
            return LoadPlan.objects.filter(theresource__exact=args[0]).select_related() \
              .extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name"})
        else:
            return LoadPlan.objects.select_related() \
              .extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name"})

    @classmethod
    def extra_context(reportclass, request, *args, **kwargs):
        return {'active_tab': 'plandetail'}

    rows = (
        GridFieldText('theresource',
                      title=_('resource'),
                      key=True,
                      formatter='resource',
                      editable=False),
        GridFieldText('operationplan__operation',
                      title=_('operation'),
                      formatter='operation',
                      editable=False),
        GridFieldDateTime('startdate', title=_('start date'), editable=False),
        GridFieldDateTime('enddate', title=_('end date'), editable=False),
        GridFieldNumber('operationplan__quantity',
                        title=_('operationplan quantity'),
                        editable=False),
        GridFieldNumber('quantity', title=_('load quantity'), editable=False),
        GridFieldNumber('operationplan__criticality',
                        title=_('criticality'),
                        editable=False),
        GridFieldBool('operationplan__locked',
                      title=_('locked'),
                      editable=False),
        GridFieldNumber('operationplan__unavailable',
                        title=_('unavailable'),
                        editable=False),
        GridFieldInteger('operationplan',
                         title=_('operationplan'),
                         editable=False),
        GridFieldText('setup', title=_('setup'), editable=False),
    )
Example #12
0
def getAttributeFields(model, related_name_prefix=None, initially_hidden=False):
  '''
  Return report fields for all attributes of a given model.
  '''
  from freppledb.common.report import GridFieldText, GridFieldBool, GridFieldNumber
  from freppledb.common.report import GridFieldInteger, GridFieldDate, GridFieldDateTime
  from freppledb.common.report import GridFieldDuration, GridFieldTime
  result = []
  for field_name, label, fieldtype in _register.get("%s.%s" % (model.__module__, model.__name__), []):
    if related_name_prefix:
      field_name = "%s__%s" % (related_name_prefix, field_name)
      label = "%s - %s" % (related_name_prefix.split('__')[-1], label)
    else:
      label = "%s - %s" % (model.__name__, label)
    if fieldtype == 'string':
      result.append( GridFieldText(field_name, title=label, initially_hidden=initially_hidden) )
    elif fieldtype == 'boolean':
      result.append( GridFieldBool(field_name, title=label, initially_hidden=initially_hidden) )
    elif fieldtype == 'number':
      result.append( GridFieldNumber(field_name, title=label, initially_hidden=initially_hidden) )
    elif fieldtype == 'integer':
      result.append( GridFieldInteger(field_name, title=label, initially_hidden=initially_hidden) )
    elif fieldtype == 'date':
      result.append( GridFieldDate(field_name, title=label, initially_hidden=initially_hidden) )
    elif fieldtype == 'datetime':
      result.append( GridFieldDateTime(field_name, title=label, initially_hidden=initially_hidden) )
    elif fieldtype == 'duration':
      result.append( GridFieldDuration(field_name, title=label, initially_hidden=initially_hidden) )
    elif fieldtype == 'time':
      result.append( GridFieldTime(field_name, title=label, initially_hidden=initially_hidden) )
    else:
      raise Exception("Invalid attribute type '%s'." % fieldtype)
  return result
Example #13
0
class CalendarBucketList(GridReport):
    '''
  A list report to show calendar buckets.
  '''
    template = 'input/calendarbucketlist.html'
    title = _("Calendar Bucket List")
    basequeryset = CalendarBucket.objects.all()
    model = CalendarBucket
    frozenColumns = 3
    rows = (
        GridFieldInteger('id',
                         title=_('identifier'),
                         formatter='calendarbucket'),
        GridFieldText('calendar',
                      title=_('calendar'),
                      field_name='calendar__name',
                      formatter='calendar'),
        GridFieldDateTime('startdate', title=_('start date')),
        GridFieldDateTime('enddate', title=_('end date'), editable=False),
        GridFieldNumber('value', title=_('value')),
        GridFieldInteger('priority', title=_('priority')),
        GridFieldBool('monday', title=_('Monday')),
        GridFieldBool('tuesday', title=_('Tuesday')),
        GridFieldBool('wednesday', title=_('Wednesday')),
        GridFieldBool('thursday', title=_('Thursday')),
        GridFieldBool('friday', title=_('Friday')),
        GridFieldBool('saturday', title=_('Saturday')),
        GridFieldBool('sunday', title=_('Sunday')),
        GridFieldTime('starttime', title=_('start time')),
        GridFieldTime('endtime', title=_('end time')),
        GridFieldText(
            'source', title=_('source')
        ),  # Not really right, since the engine doesn't read or store it
        GridFieldLastModified('lastmodified'),
    )
Example #14
0
class OperationPlanList(GridReport):
    '''
  A list report to show operationplans.
  '''
    template = 'input/operationplanlist.html'
    title = _("Operationplan List")
    basequeryset = OperationPlan.objects.all()
    model = OperationPlan
    frozenColumns = 1

    rows = (
        GridFieldInteger('id', title=_('identifier'), key=True),
        GridFieldText('operation',
                      title=_('operation'),
                      field_name='operation__name',
                      formatter='operation'),
        GridFieldDateTime('startdate', title=_('start date')),
        GridFieldDateTime('enddate', title=_('end date')),
        GridFieldNumber('quantity', title=_('quantity')),
        GridFieldChoice('status',
                        title=_('status'),
                        choices=OperationPlan.orderstatus),
        GridFieldInteger('owner',
                         title=_('owner'),
                         extra="formatoptions:{defaultValue:''}"),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #15
0
 def rows(self, request, *args, **kwargs):
     cols = []
     if args:
         for c in (
             SQLColumn.objects.using(request.database)
             .filter(report=args[0])
             .order_by("sequence")
         ):
             if c.format == "number":
                 cols.append(GridFieldNumber(_(c.name), editable=False))
             elif c.format == "datetime":
                 cols.append(GridFieldDateTime(_(c.name), editable=False))
             elif c.format == "date":
                 cols.append(GridFieldDate(_(c.name), editable=False))
             elif c.format == "integer":
                 cols.append(GridFieldInteger(_(c.name), editable=False))
             elif c.format == "duration":
                 cols.append(GridFieldDuration(_(c.name), editable=False))
             elif c.format == "text":
                 cols.append(GridFieldText(_(c.name), editable=False))
             elif c.format == "character":
                 cols.append(GridFieldText(_(c.name), editable=False))
             elif c.format == "bool":
                 cols.append(GridFieldBool(_(c.name), editable=False))
             elif c.format == "currency":
                 cols.append(GridFieldCurrency(_(c.name), editable=False))
     return cols
Example #16
0
class BaseReport(GridReport):
  '''
  A list report to show constraints.
  '''
  template = 'output/constraint.html'
  title = _("Constraint report")
  basequeryset = Constraint.objects.all()
  model = Constraint
  permissions = (("view_constraint_report", "Can view constraint report"),)
  frozenColumns = 0
  editable = False
  multiselect = False
  help_url = 'user-guide/user-interface/plan-analysis/constraint-report.html'
  rows = (
    GridFieldInteger('id', title=_('id'),  key=True,editable=False, hidden=True),
    GridFieldText('demand', title=_('demand'), editable=False, formatter='detail', extra="role:'input/demand'"),
    GridFieldText('entity', title=_('entity'), editable=False, width=80, align='center'),
    #. Translators: Translation included with Django
    GridFieldText('name', title=_('name'), editable=False, width=100, align='center'),
    GridFieldText('owner', title=_('owner'), editable=False, extra='formatter:probfmt'),
    GridFieldText('description', title=_('description'), editable=False, width=350),
    GridFieldDateTime('startdate', title=_('start date'), editable=False),
    GridFieldDateTime('enddate', title=_('end date'), editable=False),
    GridFieldNumber('weight', title=_('weight'), editable=False),
    )

  @classmethod
  def extra_context(reportclass, request, *args, **kwargs):
    if args and args[0]:
      request.session['lasttab'] = 'constraint'
    return {'active_tab': 'constraint'}
Example #17
0
class Report(GridReport):
    '''
  A list report to show problems.
  '''
    template = 'output/problem.html'
    title = _("Problem Report")
    basequeryset = Problem.objects  # TODO .extra(select={'forecast': "select name from forecast where out_problem.owner like forecast.name || ' - %%'",})
    model = Problem
    permissions = (("view_problem_report", "Can view problem report"), )
    frozenColumns = 0
    editable = False
    multiselect = False
    rows = (
        GridFieldText('entity',
                      title=_('entity'),
                      editable=False,
                      align='center'),  # TODO choices=getEntities
        GridFieldText('name', title=_('name'), editable=False,
                      align='center'),  # TODO choices=getNames
        GridFieldText('owner',
                      title=_('owner'),
                      editable=False,
                      extra='formatter:probfmt'),
        GridFieldText('description',
                      title=_('description'),
                      editable=False,
                      width=350),
        GridFieldDateTime('startdate', title=_('start date'), editable=False),
        GridFieldDateTime('enddate', title=_('end date'), editable=False),
        GridFieldNumber('weight', title=_('weight'), editable=False),
    )
Example #18
0
class BaseReport(GridReport):
  '''
  A list report to show constraints.
  '''
  template = 'output/constraint.html'
  title = _("Constraint Report")
  basequeryset = Constraint.objects.all()
  model = Constraint
  permissions = (("view_constraint_report", "Can view constraint report"),)
  frozenColumns = 0
  editable = False
  multiselect = False
  rows = (
    GridFieldText('demand', title=_('demand'), editable=False, formatter='demand'),
    GridFieldText('entity', title=_('entity'), editable=False, width=80, align='center'),
    GridFieldText('name', title=_('name'), editable=False, width=100, align='center'),
    GridFieldText('owner', title=_('owner'), editable=False, extra='formatter:probfmt'),
    GridFieldText('description', title=_('description'), editable=False, width=350),
    GridFieldDateTime('startdate', title=_('start date'), editable=False),
    GridFieldDateTime('enddate', title=_('end date'), editable=False),
    GridFieldNumber('weight', title=_('weight'), editable=False),
    )

  @classmethod
  def extra_context(reportclass, request, *args, **kwargs):
    return {'active_tab': 'constraint'}
Example #19
0
class Report(GridReport):
    """
  A list report to show problems.
  """

    template = "output/problem.html"
    title = _("Problem report")
    basequeryset = (
        Problem.objects
    )  # TODO .extra(select={'forecast': "select name from forecast where out_problem.owner like forecast.name || ' - %%'",})
    model = Problem
    permissions = (("view_problem_report", "Can view problem report"),)
    frozenColumns = 0
    editable = False
    multiselect = False
    help_url = "user-guide/user-interface/plan-analysis/problem-report.html"
    rows = (
        # . Translators: Translation included with Django
        GridFieldInteger("id", title=_("id"), key=True, editable=False, hidden=True),
        GridFieldText(
            "entity", title=_("entity"), editable=False, align="center"
        ),  # TODO choices=getEntities
        # . Translators: Translation included with Django
        GridFieldText(
            "name", title=_("name"), editable=False, align="center"
        ),  # TODO choices=getNames
        GridFieldText(
            "owner", title=_("owner"), editable=False, extra='"formatter":probfmt'
        ),
        GridFieldText("description", title=_("description"), editable=False, width=350),
        GridFieldDateTime("startdate", title=_("start date"), editable=False),
        GridFieldDateTime("enddate", title=_("end date"), editable=False),
        GridFieldNumber("weight", title=_("weight"), editable=False),
    )
Example #20
0
class BaseReport(GridReport):
    """
  A list report to show constraints.
  """

    template = "output/constraint.html"
    title = _("Constraint report")
    basequeryset = Constraint.objects.all()
    model = Constraint
    permissions = (("view_constraint_report", "Can view constraint report"),)
    frozenColumns = 0
    editable = False
    multiselect = False
    help_url = "user-interface/plan-analysis/constraint-report.html"
    detail_post_title = _("constrained demand")
    detailmodel = None
    rows = (
        GridFieldInteger("id", title=_("id"), key=True, editable=False, hidden=True),
        GridFieldText(
            "demand",
            title=_("demand"),
            editable=False,
            formatter="detail",
            extra='"role":"input/demand"',
        ),
        GridFieldText(
            "entity", title=_("entity"), editable=False, width=80, align="center"
        ),
        GridFieldText(
            "name", title=_("name"), editable=False, width=100, align="center"
        ),
        GridFieldText(
            "owner", title=_("owner"), editable=False, extra='"formatter":probfmt'
        ),
        GridFieldText("description", title=_("description"), editable=False, width=350),
        GridFieldDateTime("startdate", title=_("start date"), editable=False),
        GridFieldDateTime("enddate", title=_("end date"), editable=False),
        GridFieldNumber("weight", title=_("weight"), editable=False),
    )

    @classmethod
    def extra_context(reportclass, request, *args, **kwargs):
        if args and args[0] and reportclass.detailmodel:
            request.session["lasttab"] = "constraint"
            if (
                reportclass.detailmodel._meta.model_name == "buffer"
                and " @ " not in args[0]
            ):
                b = Buffer.objects.get(id=args[0])
                bufferName = b.item.name + " @ " + b.location.name
            return {
                "active_tab": "constraint",
                "title": force_text(reportclass.detailmodel._meta.verbose_name)
                + " "
                + (bufferName if "bufferName" in vars() else args[0]),
                "post_title": reportclass.detail_post_title,
            }
        else:
            return {"active_tab": "constraint"}
Example #21
0
class DetailReport(GridReport):
  '''
  A list report to show OperationPlanResources.
  '''
  template = 'output/loadplan.html'
  title = _("Resource detail report")
  model = OperationPlanResource
  permissions = (("view_resource_report", "Can view resource report"),)
  frozenColumns = 0
  editable = False
  multiselect = False
  help_url = 'user-guide/user-interface/plan-analysis/resource-detail-report.html'
  
  @ classmethod
  def basequeryset(reportclass, request, args, kwargs):
    if args and args[0]:
      base = OperationPlanResource.objects.filter(resource__exact=args[0])
    else:
      base = OperationPlanResource.objects
    return base.select_related().extra(select={
      'pegging': "(select string_agg(value || ' : ' || key, ', ') from (select key, value from json_each_text(plan) order by key desc) peg)"
      })

  @classmethod
  def extra_context(reportclass, request, *args, **kwargs):
    if args and args[0]:
      request.session['lasttab'] = 'plandetail'
    return {'active_tab': 'plandetail'}

  rows = (
    GridFieldInteger('id', title=_('id'),  key=True,editable=False, hidden=True),
    GridFieldText('resource', title=_('resource'), editable=False, formatter='detail', extra="role:'input/resource'"),
    GridFieldText('operationplan__type', title=_('type'), field_name='operationplan__type', editable=False),
    GridFieldText('operationplan__operation', title=_('operation'), editable=False, formatter='detail', extra="role:'input/operation'"),
    GridFieldDateTime('startdate', title=_('start date'), editable=False),
    GridFieldDateTime('enddate', title=_('end date'), editable=False),
    GridFieldNumber('operationplan__quantity', title=_('operationplan quantity'), editable=False),
    GridFieldText('pegging', title=_('demand quantity'), formatter='demanddetail', extra="role:'input/demand'", width=300, editable=False, sortable=False),
    GridFieldNumber('quantity', title=_('load quantity'), editable=False),
    GridFieldNumber('operationplan__criticality', title=_('criticality'), editable=False),
    GridFieldBool('operationplan__status', title=_('status'), editable=False),
    GridFieldText('setup', title=_('setup'), editable=False),
    )
Example #22
0
class BufferList(GridReport):
    '''
  A list report to show buffers.
  '''
    template = 'input/bufferlist.html'
    title = _("Buffer List")
    basequeryset = Buffer.objects.all()
    model = Buffer
    frozenColumns = 1

    rows = (
        GridFieldText('name', title=_('name'), key=True, formatter='buffer'),
        GridFieldText('description', title=_('description')),
        GridFieldText('category', title=_('category')),
        GridFieldText('subcategory', title=_('subcategory')),
        GridFieldText('location',
                      title=_('location'),
                      field_name='location__name',
                      formatter='location'),
        GridFieldText('item',
                      title=_('item'),
                      field_name='item__name',
                      formatter='item'),
        GridFieldNumber('onhand', title=_('onhand')),
        GridFieldText('owner',
                      title=_('owner'),
                      field_name='owner__name',
                      formatter='buffer'),
        GridFieldChoice('type', title=_('type'), choices=Buffer.types),
        GridFieldNumber('minimum', title=_('minimum')),
        GridFieldText('minimum_calendar',
                      title=_('minimum calendar'),
                      field_name='minimum_calendar__name',
                      formatter='calendar'),
        GridFieldText('producing',
                      title=_('producing'),
                      field_name='producing__name',
                      formatter='operation'),
        GridFieldNumber('carrying_cost', title=_('carrying cost')),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #23
0
class DemandList(GridReport):
    '''
  A list report to show demands.
  '''
    template = 'input/demandlist.html'
    title = _("Demand List")
    basequeryset = Demand.objects.all()
    model = Demand
    frozenColumns = 1

    rows = (
        GridFieldText('name', title=_('name'), key=True, formatter='demand'),
        GridFieldText('item',
                      title=_('item'),
                      field_name='item__name',
                      formatter='item'),
        GridFieldText('location',
                      title=_('location'),
                      field_name='location__name',
                      formatter='location'),
        GridFieldText('customer',
                      title=_('customer'),
                      field_name='customer__name',
                      formatter='customer'),
        GridFieldText('description', title=_('description')),
        GridFieldText('category', title=_('category')),
        GridFieldText('subcategory', title=_('subcategory')),
        GridFieldDateTime('due', title=_('due')),
        GridFieldNumber('quantity', title=_('quantity')),
        GridFieldText('operation',
                      title=_('delivery operation'),
                      formatter='operation'),
        GridFieldInteger('priority', title=_('priority')),
        GridFieldText('owner', title=_('owner'), formatter='demand'),
        GridFieldChoice('status',
                        title=_('status'),
                        choices=Demand.demandstatus),
        GridFieldDuration('maxlateness', title=_('maximum lateness')),
        GridFieldNumber('minshipment', title=_('minimum shipment')),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #24
0
class ResourceList(GridReport):
    '''
  A list report to show resources.
  '''
    template = 'input/resourcelist.html'
    title = _("Resource List")
    basequeryset = Resource.objects.all()
    model = Resource
    frozenColumns = 1

    rows = (
        GridFieldText('name', title=_('name'), key=True, formatter='resource'),
        GridFieldText('description', title=_('description')),
        GridFieldText('category', title=_('category')),
        GridFieldText('subcategory', title=_('subcategory')),
        GridFieldText('location',
                      title=_('location'),
                      field_name='location__name',
                      formatter='location'),
        GridFieldText('owner',
                      title=_('owner'),
                      field_name='owner__name',
                      formatter='resource'),
        GridFieldChoice('type', title=_('type'), choices=Resource.types),
        GridFieldNumber('maximum', title=_('maximum')),
        GridFieldText('maximum_calendar',
                      title=_('maximum calendar'),
                      field_name='maximum_calendar__name',
                      formatter='calendar'),
        GridFieldCurrency('cost', title=_('cost')),
        GridFieldNumber('maxearly', title=_('maxearly')),
        GridFieldText('setupmatrix',
                      title=_('setup matrix'),
                      formatter='setupmatrix'),
        GridFieldText('setup', title=_('setup')),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #25
0
class DistributionOrderList(GridReport):
    '''
  A list report to show distribution orders.
  '''
    template = 'input/distributionorderlist.html'
    title = _("Distribution order List")
    basequeryset = DistributionOrder.objects.all()
    model = DistributionOrder
    frozenColumns = 1

    rows = (
        GridFieldInteger('id', title=_('identifier'), key=True),
        GridFieldText('reference', title=_('reference')),
        GridFieldChoice('status',
                        title=_('status'),
                        choices=DistributionOrder.orderstatus),
        GridFieldText('item',
                      title=_('item'),
                      field_name='item__name',
                      formatter='item'),
        GridFieldText('origin',
                      title=_('origin'),
                      field_name='origin__name',
                      formatter='location'),
        GridFieldText('destination',
                      title=_('destination'),
                      field_name='origin__name',
                      formatter='location'),
        GridFieldDateTime('startdate', title=_('start date')),
        GridFieldDateTime('enddate', title=_('end date')),
        GridFieldNumber('quantity', title=_('quantity')),
        GridFieldBool('consume_material', title=_('consume material')),
        GridFieldNumber('criticality', title=_('criticality'), editable=False),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #26
0
class CalendarList(GridReport):
    '''
  A list report to show calendars.
  '''
    template = 'input/calendarlist.html'
    title = _("Calendar List")
    basequeryset = Calendar.objects.all()
    model = Calendar
    frozenColumns = 1
    rows = (
        GridFieldText('name', title=_('name'), key=True, formatter='calendar'),
        GridFieldText('description', title=_('description')),
        GridFieldText('category', title=_('category')),
        GridFieldText('subcategory', title=_('subcategory')),
        GridFieldNumber('defaultvalue', title=_('default value')),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #27
0
class Report(GridReport):
    '''
  A list report to show problems.
  '''
    template = 'output/problem.html'
    title = _("Problem report")
    basequeryset = Problem.objects  # TODO .extra(select={'forecast': "select name from forecast where out_problem.owner like forecast.name || ' - %%'",})
    model = Problem
    permissions = (("view_problem_report", "Can view problem report"), )
    frozenColumns = 0
    editable = False
    multiselect = False
    help_url = 'user-guide/user-interface/plan-analysis/problem-report.html'
    rows = (
        #. Translators: Translation included with Django
        GridFieldInteger('id',
                         title=_('id'),
                         key=True,
                         editable=False,
                         hidden=True),
        GridFieldText('entity',
                      title=_('entity'),
                      editable=False,
                      align='center'),  # TODO choices=getEntities
        #. Translators: Translation included with Django
        GridFieldText('name', title=_('name'), editable=False,
                      align='center'),  # TODO choices=getNames
        GridFieldText('owner',
                      title=_('owner'),
                      editable=False,
                      extra='"formatter":probfmt'),
        GridFieldText('description',
                      title=_('description'),
                      editable=False,
                      width=350),
        GridFieldDateTime('startdate', title=_('start date'), editable=False),
        GridFieldDateTime('enddate', title=_('end date'), editable=False),
        GridFieldNumber('weight', title=_('weight'), editable=False),
    )
Example #28
0
class ResourceSkillList(GridReport):
    '''
  A list report to show resource skills.
  '''
    template = 'input/resourceskilllist.html'
    title = _("Resource skill List")
    basequeryset = ResourceSkill.objects.all()
    model = ResourceSkill
    frozenColumns = 1

    rows = (
        GridFieldInteger('id',
                         title=_('identifier'),
                         key=True,
                         formatter='resourceskill'),
        GridFieldText('resource', title=_('resource'), formatter='resource'),
        GridFieldText('skill', title=_('skill'), formatter='skill'),
        GridFieldDateTime('effective_start', title=_('effective start')),
        GridFieldDateTime('effective_end', title=_('effective end')),
        GridFieldNumber('priority', title=_('priority')),
        GridFieldText('source', title=_('source')),
        GridFieldLastModified('lastmodified'),
    )
Example #29
0
class MyModelList(GridReport):
    """
    This report show an editable grid for your models.
    You can sort data, filter data, import excel files, export excel files.
    """

    title = _("My models")
    basequeryset = My_Model.objects.all()
    model = My_Model
    frozenColumns = 1
    rows = (
        GridFieldText(
            "name",
            title=_("name"),
            key=True,
            formatter="detail",
            extra='"role":"my_app/my_model"',
        ),
        GridFieldText("charfield", title=_("charfield")),
        GridFieldBoolNullable("booleanfield", title=_("category")),
        GridFieldNumber("decimalfield", title=_("decimalfield")),
        GridFieldText("source", title=_("source")),
        GridFieldLastModified("lastmodified"),
    )
Example #30
0
class OverviewReport(GridPivot):
    """
    A report showing the inventory profile of buffers.
    """

    template = "output/buffer.html"
    title = _("Inventory report")
    new_arg_logic = True

    @classmethod
    def basequeryset(reportclass, request, *args, **kwargs):
        if hasattr(request, "basequeryset"):
            return request.basequeryset

        item = None
        location = None
        batch = None

        if len(args) and args[0]:
            if request.path_info.startswith(
                    "/buffer/item/") or request.path_info.startswith(
                        "/detail/input/item/"):
                item = args[0]
            else:
                i_b_l = args[0].split(" @ ")
                if len(i_b_l) == 1:
                    b = Buffer.objects.values("item",
                                              "location").get(id=args[0])
                    item = b["item"]
                    location = b["location"]
                elif len(i_b_l) == 2:
                    item = i_b_l[0]
                    location = i_b_l[1]
                else:
                    item = i_b_l[0]
                    location = i_b_l[2]
                    batch = i_b_l[1]

        request.basequeryset = OperationPlanMaterial.objects.values(
            "item", "location",
            "item__type").filter((
                (Q(item__type="make to stock") | Q(item__type__isnull=True)))
                                 | (Q(item__type="make to order")
                                    & Q(operationplan__batch__isnull=False)))

        if item:
            request.basequeryset = request.basequeryset.filter(item=item)

        if location:
            request.basequeryset = request.basequeryset.filter(
                location=location)

        if batch:
            request.basequeryset = request.basequeryset.filter(
                operationplan__batch=batch)

        request.basequeryset = request.basequeryset.annotate(
            buffer=RawSQL(
                "operationplanmaterial.item_id || "
                "(case when item.type is distinct from 'make to order' then '' else ' @ ' || operationplan.batch end) "
                "|| ' @ ' || operationplanmaterial.location_id",
                (),
            ),
            opplan_batch=RawSQL(
                "case when item.type is distinct from 'make to order' then '' else operationplan.batch end",
                (),
            ),
        ).distinct()

        return request.basequeryset

    model = OperationPlanMaterial
    default_sort = (1, "asc", 2, "asc")
    permissions = (("view_inventory_report", "Can view inventory report"), )
    help_url = "user-guide/user-interface/plan-analysis/inventory-report.html"

    rows = (
        GridFieldText("buffer",
                      title=_("buffer"),
                      editable=False,
                      key=True,
                      initially_hidden=True),
        GridFieldText(
            "item",
            title=_("item"),
            editable=False,
            field_name="item__name",
            formatter="detail",
            extra='"role":"input/item"',
        ),
        GridFieldText(
            "location",
            title=_("location"),
            editable=False,
            field_name="location__name",
            formatter="detail",
            extra='"role":"input/location"',
        ),
        # Optional fields referencing the item
        GridFieldText(
            "item__description",
            title=format_lazy("{} - {}", _("item"), _("description")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "item__type",
            title=format_lazy("{} - {}", _("item"), _("type")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "item__category",
            title=format_lazy("{} - {}", _("item"), _("category")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "item__subcategory",
            title=format_lazy("{} - {}", _("item"), _("subcategory")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldNumber(
            "item__cost",
            title=format_lazy("{} - {}", _("item"), _("cost")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "item__owner",
            title=format_lazy("{} - {}", _("item"), _("owner")),
            field_name="item__owner__name",
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "item__source",
            title=format_lazy("{} - {}", _("item"), _("source")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldLastModified(
            "item__lastmodified",
            title=format_lazy("{} - {}", _("item"), _("last modified")),
            initially_hidden=True,
            editable=False,
        ),
        # Optional fields referencing the location
        GridFieldText(
            "location__description",
            title=format_lazy("{} - {}", _("location"), _("description")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "location__category",
            title=format_lazy("{} - {}", _("location"), _("category")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "location__subcategory",
            title=format_lazy("{} - {}", _("location"), _("subcategory")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "location__available",
            title=format_lazy("{} - {}", _("location"), _("available")),
            initially_hidden=True,
            field_name="origin__available__name",
            formatter="detail",
            extra='"role":"input/calendar"',
            editable=False,
        ),
        GridFieldText(
            "location__owner",
            title=format_lazy("{} - {}", _("location"), _("owner")),
            initially_hidden=True,
            field_name="origin__owner__name",
            formatter="detail",
            extra='"role":"input/location"',
            editable=False,
        ),
        GridFieldText(
            "location__source",
            title=format_lazy("{} - {}", _("location"), _("source")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldLastModified(
            "location__lastmodified",
            title=format_lazy("{} - {}", _("location"), _("last modified")),
            initially_hidden=True,
            editable=False,
        ),
        GridFieldText(
            "batch",
            title=_("batch"),
            field_name="opplan_batch",
            editable=False,
            initially_hidden=True,
        ),
    )

    crosses = (
        ("startoh", {
            "title": _("start inventory")
        }),
        ("startohdoc", {
            "title": _("start inventory days of cover")
        }),
        ("safetystock", {
            "title": _("safety stock")
        }),
        ("consumed", {
            "title": _("total consumed")
        }),
        ("consumedMO", {
            "title": _("consumed by MO")
        }),
        ("consumedDO", {
            "title": _("consumed by DO")
        }),
        ("consumedSO", {
            "title": _("consumed by SO")
        }),
        ("produced", {
            "title": _("total produced")
        }),
        ("producedMO", {
            "title": _("produced by MO")
        }),
        ("producedDO", {
            "title": _("produced by DO")
        }),
        ("producedPO", {
            "title": _("produced by PO")
        }),
        ("endoh", {
            "title": _("end inventory")
        }),
        ("total_in_progress", {
            "title": _("total in progress")
        }),
        ("work_in_progress_mo", {
            "title": _("work in progress MO")
        }),
        ("on_order_po", {
            "title": _("on order PO")
        }),
        ("in_transit_do", {
            "title": _("in transit DO")
        }),
    )

    @classmethod
    def initialize(reportclass, request):
        if reportclass._attributes_added != 2:
            reportclass._attributes_added = 2
            reportclass.attr_sql = ""
            # Adding custom item attributes
            for f in getAttributeFields(Item,
                                        related_name_prefix="item",
                                        initially_hidden=True):
                reportclass.rows += (f, )
                reportclass.attr_sql += "item.%s, " % f.name.split("__")[-1]
            # Adding custom location attributes
            for f in getAttributeFields(Location,
                                        related_name_prefix="location",
                                        initially_hidden=True):
                reportclass.rows += (f, )
                reportclass.attr_sql += "location.%s, " % f.name.split(
                    "__")[-1]

    @classmethod
    def extra_context(reportclass, request, *args, **kwargs):
        if not hasattr(request, "basequeryset"):
            reportclass.basequeryset(request, *args, **kwargs)
        if args and args[0]:
            if request.path_info.startswith(
                    "/buffer/item/") or request.path_info.startswith(
                        "/detail/input/item/"):
                request.session["lasttab"] = "inventory"
                r = {
                    "title":
                    force_text(Item._meta.verbose_name) + " " + args[0],
                    "post_title": _("inventory"),
                    "active_tab": "inventory",
                }
                if request.basequeryset.using(request.database).count() <= 1:
                    r["args"] = args
                    r["mode"] = "table"
                else:
                    r["args"] = None
                return r
            else:
                request.session["lasttab"] = "plan"
                index = args[0].find(" @ ")
                if index == -1:
                    buffer = Buffer.objects.get(id=args[0])
                return {
                    "title":
                    force_text(Buffer._meta.verbose_name) + " " +
                    (args[0] if index != -1 else buffer.item.name + " @ " +
                     buffer.location.name),
                    "post_title":
                    _("plan"),
                    "active_tab":
                    "plan",
                }
        else:
            return {}

    @classmethod
    def query(reportclass, request, basequery, sortsql="1 asc"):
        basesql, baseparams = basequery.query.get_compiler(
            basequery.db).as_sql(with_col_aliases=False)

        # Execute the actual query
        query = """
           select
           opplanmat.buffer,
           item.name item_id,
           location.name location_id,
           item.description,
           item.type,
           item.category,
           item.subcategory,
           item.cost,
           item.owner_id,
           item.source,
           item.lastmodified,
           location.description,
           location.category,
           location.subcategory,
           location.available_id,
           location.owner_id,
           location.source,
           location.lastmodified,
           opplanmat.opplan_batch,
           %s
           (select jsonb_build_object(
               'onhand', onhand,
               'flowdate', to_char(flowdate,'YYYY-MM-DD HH24:MI:SS'),
               'periodofcover', periodofcover
               )
           from operationplanmaterial
           inner join operationplan
             on operationplanmaterial.operationplan_id = operationplan.reference
           where operationplanmaterial.item_id = item.name
             and operationplanmaterial.location_id = location.name
             and (item.type is distinct from 'make to order' or operationplan.batch is not distinct from opplanmat.opplan_batch)
             and flowdate < greatest(d.startdate,%%s)
           order by flowdate desc, id desc limit 1) startoh,
           d.bucket,
           d.startdate,
           d.enddate,
           (select safetystock from
            (
            select 1 as priority, coalesce(
              (select value from calendarbucket
               where calendar_id = 'SS for ' || opplanmat.buffer
               and greatest(d.startdate,%%s) >= startdate and greatest(d.startdate,%%s) < enddate
               order by priority limit 1),
              (select defaultvalue from calendar where name = 'SS for ' || opplanmat.buffer)
              ) as safetystock
            union all
            select 2 as priority, coalesce(
              (select value
               from calendarbucket
               where calendar_id = (
                 select minimum_calendar_id
                 from buffer
                 where item_id = item.name
                 and location_id = location.name
                 and (item.type is distinct from 'make to order' or buffer.batch is not distinct from opplanmat.opplan_batch)
                 )
               and greatest(d.startdate,%%s) >= startdate
               and greatest(d.startdate,%%s) < enddate
               order by priority limit 1),
              (select defaultvalue
               from calendar
               where name = (
                 select minimum_calendar_id
                 from buffer
                 where item_id = item.name
                 and location_id = location.name
                 and (item.type is distinct from 'make to order' or buffer.batch is not distinct from opplanmat.opplan_batch)
                 )
              )
            ) as safetystock
            union all
            select 3 as priority, minimum as safetystock
            from buffer
            where item_id = item.name
            and location_id = location.name
            and (item.type is distinct from 'make to order' or buffer.batch is not distinct from opplanmat.opplan_batch)
            ) t
            where t.safetystock is not null
            order by priority
            limit 1) safetystock,
            (select jsonb_build_object(
               'work_in_progress_mo', sum(case when (startdate < d.enddate and enddate >= d.enddate) and opm.quantity > 0 and operationplan.type = 'MO' then opm.quantity else 0 end),
               'on_order_po', sum(case when (startdate < d.enddate and enddate >= d.enddate) and opm.quantity > 0 and operationplan.type = 'PO' then opm.quantity else 0 end),
               'in_transit_do', sum(case when (startdate < d.enddate and enddate >= d.enddate) and opm.quantity > 0 and operationplan.type = 'DO' then opm.quantity else 0 end),
               'total_in_progress', sum(case when (startdate < d.enddate and enddate >= d.enddate) and opm.quantity > 0 then opm.quantity else 0 end),
               'consumed', sum(case when (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity < 0 then -opm.quantity else 0 end),
               'consumedMO', sum(case when operationplan.type = 'MO' and (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity < 0 then -opm.quantity else 0 end),
               'consumedDO', sum(case when operationplan.type = 'DO' and (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity < 0 then -opm.quantity else 0 end),
               'consumedSO', sum(case when operationplan.type = 'DLVR' and (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity < 0 then -opm.quantity else 0 end),
               'produced', sum(case when (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity > 0 then opm.quantity else 0 end),
               'producedMO', sum(case when operationplan.type = 'MO' and (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity > 0 then opm.quantity else 0 end),
               'producedDO', sum(case when operationplan.type = 'DO' and (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity > 0 then opm.quantity else 0 end),
               'producedPO', sum(case when operationplan.type = 'PO' and (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate) and opm.quantity > 0 then opm.quantity else 0 end)
               )
             from operationplanmaterial opm
             inner join operationplan
             on operationplan.reference = opm.operationplan_id
               and ((startdate < d.enddate and enddate >= d.enddate)
               or (opm.flowdate >= greatest(d.startdate,%%s) and opm.flowdate < d.enddate))
             where opm.item_id = item.name
               and opm.location_id = location.name
               and (item.type is distinct from 'make to order' or operationplan.batch is not distinct from opplanmat.opplan_batch)
           ) ongoing
           from
           (%s) opplanmat
           inner join item on item.name = opplanmat.item_id
           inner join location on location.name = opplanmat.location_id
           -- Multiply with buckets
          cross join (
             select name as bucket, startdate, enddate
             from common_bucketdetail
             where bucket_id = %%s and enddate > %%s and startdate < %%s
             ) d
          group by
           opplanmat.buffer,
           item.name,
           location.name,
           item.description,
           item.type,
           item.category,
           item.subcategory,
           item.cost,
           item.owner_id,
           item.source,
           item.lastmodified,
           location.description,
           location.category,
           location.subcategory,
           location.available_id,
           location.owner_id,
           location.source,
           location.lastmodified,
           opplanmat.opplan_batch,
           d.bucket,
           d.startdate,
           d.enddate
           order by %s, d.startdate
        """ % (
            reportclass.attr_sql,
            basesql,
            sortsql,
        )

        # Build the python result
        with connections[request.database].chunked_cursor() as cursor_chunked:
            cursor_chunked.execute(
                query,
                (
                    request.report_startdate,  # startoh
                    request.report_startdate,
                    request.report_startdate,
                    request.report_startdate,
                    request.report_startdate,  # safetystock
                ) + (request.report_startdate, ) * 9 + baseparams  # ongoing
                + (  # opplanmat
                    request.report_bucket,
                    request.report_startdate,
                    request.report_enddate,
                ),  # bucket d
            )
            for row in cursor_chunked:
                numfields = len(row)
                res = {
                    "buffer":
                    row[0],
                    "item":
                    row[1],
                    "location":
                    row[2],
                    "item__description":
                    row[3],
                    "item__type":
                    row[4],
                    "item__category":
                    row[5],
                    "item__subcategory":
                    row[6],
                    "item__cost":
                    row[7],
                    "item__owner":
                    row[8],
                    "item__source":
                    row[9],
                    "item__lastmodified":
                    row[10],
                    "location__description":
                    row[11],
                    "location__category":
                    row[12],
                    "location__subcategory":
                    row[13],
                    "location__available_id":
                    row[14],
                    "location__owner_id":
                    row[15],
                    "location__source":
                    row[16],
                    "location__lastmodified":
                    row[17],
                    "batch":
                    row[18],
                    "startoh":
                    row[numfields - 6]["onhand"] if row[numfields - 6] else 0,
                    "startohdoc":
                    max(
                        0,
                        0 if
                        (row[numfields - 6]["onhand"] if row[numfields -
                                                             6] else 0) <= 0
                        else
                        (999 if row[numfields -
                                    6]["periodofcover"] == 86313600 else
                         (datetime.strptime(row[numfields - 6]["flowdate"],
                                            "%Y-%m-%d %H:%M:%S") +
                          timedelta(seconds=row[numfields -
                                                6]["periodofcover"]) -
                          row[numfields -
                              4]).days if row[numfields -
                                              6]["periodofcover"] else 999),
                    ),
                    "bucket":
                    row[numfields - 5],
                    "startdate":
                    row[numfields - 4],
                    "enddate":
                    row[numfields - 3],
                    "safetystock":
                    row[numfields - 2] or 0,
                    "consumed":
                    row[numfields - 1]["consumed"] or 0,
                    "consumedMO":
                    row[numfields - 1]["consumedMO"] or 0,
                    "consumedDO":
                    row[numfields - 1]["consumedDO"] or 0,
                    "consumedSO":
                    row[numfields - 1]["consumedSO"] or 0,
                    "produced":
                    row[numfields - 1]["produced"] or 0,
                    "producedMO":
                    row[numfields - 1]["producedMO"] or 0,
                    "producedDO":
                    row[numfields - 1]["producedDO"] or 0,
                    "producedPO":
                    row[numfields - 1]["producedPO"] or 0,
                    "total_in_progress":
                    row[numfields - 1]["total_in_progress"] or 0,
                    "work_in_progress_mo":
                    row[numfields - 1]["work_in_progress_mo"] or 0,
                    "on_order_po":
                    row[numfields - 1]["on_order_po"] or 0,
                    "in_transit_do":
                    row[numfields - 1]["in_transit_do"] or 0,
                    "endoh":
                    float(row[numfields - 6]["onhand"] if row[numfields -
                                                              6] else 0) +
                    float(row[numfields - 1]["produced"] or 0) -
                    float(row[numfields - 1]["consumed"] or 0),
                }
                # Add attribute fields
                idx = 17
                for f in getAttributeFields(Item, related_name_prefix="item"):
                    res[f.field_name] = row[idx]
                    idx += 1
                for f in getAttributeFields(Location,
                                            related_name_prefix="location"):
                    res[f.field_name] = row[idx]
                    idx += 1
                yield res