class UserList(GridReport): ''' A list report to show users. ''' #. Translators: Translation included with Django title = _("users") basequeryset = User.objects.all() model = User frozenColumns = 2 permissions = (("change_user", "Can change user"), ) help_url = 'user-guide/user-interface/getting-around/user-permissions-and-roles.html' rows = ( #. Translators: Translation included with Django GridFieldInteger('id', title=_('id'), key=True, formatter='admin', extra='"role":"common/user"'), #. Translators: Translation included with Django GridFieldText('username', title=_('username')), #. Translators: Translation included with Django GridFieldText('email', title=_('email address'), formatter='email', width=200), #. Translators: Translation included with Django GridFieldText('first_name', title=_('first name')), #. Translators: Translation included with Django GridFieldText('last_name', title=_('last name')), #. Translators: Translation included with Django GridFieldBool('is_active', title=_('active')), #. Translators: Translation included with Django GridFieldBool('is_superuser', title=_('superuser status'), width=120), #. Translators: Translation included with Django GridFieldDateTime('date_joined', title=_('date joined'), editable=False), #. Translators: Translation included with Django GridFieldDateTime('last_login', title=_('last login'), editable=False))
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-interface/plan-analysis/problem-report.html" rows = ( GridFieldInteger("id", title=_("id"), key=True, editable=False, hidden=True), 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), )
class UserList(GridReport): ''' A list report to show users. ''' #. Translators: Translation included with Django title = _("users") basequeryset = User.objects.all() model = User frozenColumns = 2 multiselect = False permissions = (("change_user", "Can change user"), ) rows = ( #. Translators: Translation included with Django GridFieldInteger('id', title=_('id'), key=True, formatter='detail', extra="role:'common/user'"), #. Translators: Translation included with Django GridFieldText('username', title=_('username')), #. Translators: Translation included with Django GridFieldText('email', title=_('email address'), formatter='email', width=200), #. Translators: Translation included with Django GridFieldText('first_name', title=_('first name')), #. Translators: Translation included with Django GridFieldText('last_name', title=_('last name')), #. Translators: Translation included with Django GridFieldBool('is_active', title=_('active')), #. Translators: Translation included with Django GridFieldBool('is_superuser', title=_('superuser status'), width=120), #. Translators: Translation included with Django GridFieldDateTime('date_joined', title=_('date joined'), editable=False), #. Translators: Translation included with Django GridFieldDateTime('last_login', title=_('last login'), editable=False))
class GroupList(GridReport): """ A list report to show groups. """ title = _("groups") basequeryset = Group.objects.all() model = Group frozenColumns = 1 permissions = (("change_group", "Can change group"), ) help_url = "user-interface/getting-around/user-permissions-and-roles.html" rows = ( GridFieldInteger( "id", title=_("identifier"), key=True, formatter="detail", extra='"role":"auth/group"', ), GridFieldText("name", title=_("name"), width=200), )
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), )
class CommentList(GridReport): ''' A list report to display all comments. ''' template = 'common/commentlist.html' title = _('comments') basequeryset = Comment.objects.all() model = Comment editable = False multiselect = False frozenColumns = 0 rows = ( GridFieldInteger('id', title=_('identifier'), key=True), GridFieldLastModified('lastmodified'), #. Translators: Translation included with Django GridFieldText('user', title=_('user'), field_name='user__username', editable=False, align='center', width=80), GridFieldText('model', title=_('model'), field_name='content_type__model', editable=False, align='center'), GridFieldText('object_pk', title=_('object id'), field_name='object_pk', editable=False, align='center', extra='formatter:objectfmt'), GridFieldText('comment', title=_('comment'), width=400, editable=False, align='center'), GridFieldText('app', title="app", hidden=True, field_name='content_type__app_label') )
class GroupList(GridReport): ''' A list report to show groups. ''' template = 'admin/base_site_grid.html' #. Translators: Translation included with Django title = _("groups") basequeryset = Group.objects.all() model = Group frozenColumns = 0 multiselect = False permissions = (("change_group", "Can change group"), ) rows = ( GridFieldInteger('id', title=_('identifier'), key=True, formatter='detail', extra="role:'auth/group'"), #. Translators: Translation included with Django GridFieldText('name', title=_('name'), key=True, width=200), )
class CommentList(GridReport): ''' A list report to display all comments. ''' template = 'common/commentlist.html' title = _('Comments') basequeryset = Comment.objects.all() model = Comment adminsite = 'admin' editable = False multiselect = False frozenColumns = 0 rows = ( GridFieldInteger('id', title=_('identifier'), key=True), GridFieldLastModified('lastmodified'), GridFieldText('user', title=_('user'), field_name='user__username', editable=False, align='center', width=80), GridFieldText('content_type', title=_('type'), field_name='content_type__model', editable=False, align='center'), GridFieldText('object_pk', title=_('object ID'), field_name='object_pk', editable=False, align='center', extra='formatter:objectfmt'), GridFieldText('comment', title=_('comment'), editable=False, align='center'), )
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('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'), )
class BucketList(GridReport): """ A list report to show dates. """ title = _("buckets") basequeryset = Bucket.objects.all() model = Bucket frozenColumns = 1 help_url = "user-guide/model-reference/buckets.html" rows = ( GridFieldText( "name", title=_("name"), key=True, formatter="detail", extra='"role":"common/bucket"', ), GridFieldText("description", title=_("description")), GridFieldInteger("level", title=_("level")), GridFieldText("source", title=_("source")), GridFieldLastModified("lastmodified"), )
class BucketDetailList(GridReport): ''' A list report to show dates. ''' title = _("bucket dates") basequeryset = BucketDetail.objects.all() model = BucketDetail frozenColumns = 2 help_url = 'user-guide/model-reference/buckets.html' rows = ( GridFieldInteger('id', title=_('identifier'), key=True, hidden=True), GridFieldText('bucket', title=_('bucket'), field_name='bucket__name', formatter='detail', extra='"role":"common/bucket"'), GridFieldDateTime('startdate', title=_('start date')), GridFieldDateTime('enddate', title=_('end date')), #. Translators: Translation included with Django GridFieldText('name', title=_('name')), GridFieldText('source', title=_('source')), GridFieldLastModified('lastmodified'), )
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'), )
class UserList(GridReport): ''' A list report to show users. ''' template = 'common/userlist.html' title = _("User List") basequeryset = User.objects.all() model = User adminsite = 'admin' frozenColumns = 1 multiselect = False rows = ( GridFieldInteger('id', title=_('id'), key=True, formatter='user'), GridFieldText('username', title=_('username')), GridFieldText('email', title=_('email address'), formatter='email', width=200), GridFieldText('first_name', title=_('first name')), GridFieldText('last_name', title=_('last name')), GridFieldDateTime('date_joined', title=_('date joined')), GridFieldBool('is_staff', title=_('staff status')), )
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'), )
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
class UserList(GridReport): """ A list report to show users. """ title = _("users") basequeryset = User.objects.all() model = User frozenColumns = 2 permissions = (("change_user", "Can change user"), ) help_url = ( "user-guide/user-interface/getting-around/user-permissions-and-roles.html" ) rows = ( GridFieldInteger( "id", title=_("id"), key=True, formatter="admin", extra='"role":"common/user"', ), GridFieldText("username", title=_("username")), GridFieldText("email", title=_("email address"), formatter="email", width=200), GridFieldText("first_name", title=_("first name")), GridFieldText("last_name", title=_("last name")), GridFieldBool("is_active", title=_("active")), GridFieldBool("is_superuser", title=_("superuser status"), width=120), GridFieldDateTime("date_joined", title=_("date joined"), editable=False), GridFieldDateTime("last_login", title=_("last login"), editable=False), )
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, editable, hidden in getAttributes(model): 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=hidden or initially_hidden, editable=editable, )) elif fieldtype == "boolean": result.append( GridFieldBool( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) elif fieldtype == "number": result.append( GridFieldNumber( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) elif fieldtype == "integer": result.append( GridFieldInteger( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) elif fieldtype == "date": result.append( GridFieldDate( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) elif fieldtype == "datetime": result.append( GridFieldDateTime( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) elif fieldtype == "duration": result.append( GridFieldDuration( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) elif fieldtype == "time": result.append( GridFieldTime( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) elif fieldtype == "jsonb": result.append( GridFieldText( field_name, title=label, initially_hidden=hidden or initially_hidden, editable=editable, )) else: raise Exception("Invalid attribute type '%s'." % fieldtype) return result
class DeliveryOrderList(GridReport): template = "input/deliveryorder.html" title = _("delivery orders") model = DeliveryOrder frozenColumns = 0 editable = True multiselect = True help_url = "model-reference/delivery-orders.html" calendarmode = "start" rows = ( GridFieldText( "reference", title=_("reference"), key=True, formatter="detail", extra='role:"input/deliveryorder"', editable=not settings.ERP_CONNECTOR, ), GridFieldText("batch", title=_("batch"), editable="true", initially_hidden=True), GridFieldText( "demand", title=_("demand"), field_name="demand__name", formatter="detail", extra='"role":"input/demand"', ), GridFieldText( "item", title=_("item"), field_name="item__name", formatter="detail", extra='"role":"input/item"', ), GridFieldText( "customer", title=_("customer"), field_name="demand__customer__name", formatter="detail", extra='"role":"input/customer"', ), GridFieldText( "location", title=_("location"), field_name="location__name", formatter="detail", extra='"role":"input/location"', ), GridFieldNumber("quantity", title=_("quantity")), GridFieldNumber("demand__quantity", title=_("demand quantity"), editable=False), GridFieldDateTime("startdate", title=_("start date")), GridFieldDateTime( "enddate", title=_("end date"), extra=GridFieldDateTime.extra + ',"cellattr":enddatecellattr', ), GridFieldDateTime("due", field_name="demand__due", title=_("due date"), editable=False), GridFieldChoice( "status", title=_("status"), choices=OperationPlan.orderstatus, editable=not settings.ERP_CONNECTOR, ), GridFieldDuration( "delay", title=_("delay"), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), # Optional fields referencing the item GridFieldText( "item__type", title=format_lazy("{} - {}", _("item"), _("type")), initially_hidden=True, editable=False, ), GridFieldText( "item__description", title=format_lazy("{} - {}", _("item"), _("description")), 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, ), GridFieldCurrency( "item__cost", title=format_lazy("{} - {}", _("item"), _("cost")), initially_hidden=True, editable=False, ), GridFieldNumber( "item__volume", title=format_lazy("{} - {}", _("item"), _("volume")), initially_hidden=True, editable=False, ), GridFieldNumber( "item__weight", title=format_lazy("{} - {}", _("item"), _("weight")), initially_hidden=True, editable=False, ), GridFieldInteger( "item__periodofcover", title=format_lazy("{} - {}", _("item"), _("period of cover")), 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="location__available__name", formatter="detail", extra='"role":"input/calendar"', editable=False, ), GridFieldText( "location__owner", title=format_lazy("{} - {}", _("location"), _("owner")), initially_hidden=True, field_name="location__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, ), # Optional fields referencing the customer GridFieldText( "demand__customer__description", title=format_lazy("{} - {}", _("customer"), _("description")), initially_hidden=True, editable=False, ), GridFieldText( "demand__customer__category", title=format_lazy("{} - {}", _("customer"), _("category")), initially_hidden=True, editable=False, ), GridFieldText( "demand__customer__subcategory", title=format_lazy("{} - {}", _("customer"), _("subcategory")), initially_hidden=True, editable=False, ), GridFieldText( "demand__customer__owner", title=format_lazy("{} - {}", _("customer"), _("owner")), initially_hidden=True, field_name="supplier__owner__name", formatter="detail", extra='"role":"input/supplier"', editable=False, ), GridFieldText( "demand__customer__source", title=format_lazy("{} - {}", _("customer"), _("source")), initially_hidden=True, editable=False, ), GridFieldLastModified( "demand__customer__lastmodified", title=format_lazy("{} - {}", _("customer"), _("last modified")), initially_hidden=True, editable=False, ), ) @classmethod def basequeryset(reportclass, request, *args, **kwargs): q = DeliveryOrder.objects.all() if "calendarstart" in request.GET: q = q.filter( Q(enddate__gte=request.GET["calendarstart"]) | (Q(enddate__isnull=True) & Q(startdate__gte=request.GET["calendarstart"]))) if "calendarend" in request.GET: q = q.filter( Q(startdate__lte=request.GET["calendarend"]) | (Q(startdate__isnull=True) & Q(enddate__lte=request.GET["calendarend"]))) # special keyword superop used for search field of operationplan if "parentreference" in request.GET: parentreference = request.GET["parentreference"] q = q.filter(reference=parentreference) if args and args[0]: path = request.path.split("/")[4] if path == "consumed": return q.filter( item__name=args[0], location__name=args[1], enddate__gte=args[2], enddate__lt=args[3], ) else: try: itm = Item.objects.all().using( request.database).get(name=args[0]) lft = itm.lft rght = itm.rght except Item.DoesNotExist: lft = 1 rght = 1 q = q.filter(item__lft__gte=lft, item__rght__lte=rght) return q @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session["lasttab"] = "deliveryorders" path = request.path.split("/")[4] if path == "consumed": return { "active_tab": "deliveryorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": force_text( _("delivered from %(loc)s between %(date1)s and %(date2)s" ) % { "loc": args[1], "date1": args[2], "date2": args[3] }), } else: return { "active_tab": "deliveryorders", "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": _("delivery orders"), } else: return {"active_tab": "deliveryorders"} @classmethod def initialize(reportclass, request): if reportclass._attributes_added != 2: reportclass._attributes_added = 2 for f in getAttributeFields(DeliveryOrder): reportclass.rows += (f, ) for f in getAttributeFields(Item, related_name_prefix="item"): f.editable = False f.initially_hidden = True reportclass.rows += (f, ) for f in getAttributeFields(Location, related_name_prefix="location"): f.editable = False f.initially_hidden = True reportclass.rows += (f, ) for f in getAttributeFields( Customer, related_name_prefix="demand__customer"): f.editable = False f.initially_hidden = True reportclass.rows += (f, )
class DemandList(GridReport): template = "input/demand.html" title = _("sales orders") model = Demand frozenColumns = 1 help_url = "modeling-wizard/master-data/sales-orders.html" message_when_empty = Template(""" <h3>Define sales orders</h3> <br> The sales orders table contains all the orders placed by your customers.<br><br> Orders in the status "open" are still be delivered and will be planned.<br><br> <br><br> <div role="group" class="btn-group.btn-group-justified"> <a href="{{request.prefix}}/data/input/demand/add/" class="btn btn-primary">Create a single sales order<br>in a form</a> <a href="{{request.prefix}}/wizard/load/production/?currentstep=2" class="btn btn-primary">Wizard to upload sale orders<br>from a spreadsheet</a> </div> <br> """) @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] # Adding custom customer attributes for f in getAttributeFields(Customer, related_name_prefix="customer", initially_hidden=True): reportclass.rows += (f, ) reportclass.attr_sql += "customer.%s, " % f.name.split( "__")[-1] # Adding custom demand attributes for f in getAttributeFields(Demand, initially_hidden=True): reportclass.rows += (f, ) reportclass.attr_sql += "demand.%s, " % f.name.split("__")[-1] @classmethod def basequeryset(reportclass, request, *args, **kwargs): q = Demand.objects.all() if "item" in request.GET: item = Item.objects.using( request.database).get(name__exact=unquote(request.GET["item"])) q = q.filter(item__lft__gte=item.lft, item__lft__lt=item.rght) if "location" in request.GET: location = Location.objects.using(request.database).get( name__exact=unquote(request.GET["location"])) q = q.filter(location__lft__gte=location.lft, location__lft__lt=location.rght) if "customer" in request.GET: customer = Customer.objects.using(request.database).get( name__exact=unquote(request.GET["customer"])) q = q.filter(customer_lft__gte=customer.lft, customer_lft__lt=customer.rght) if "status_in" in request.GET: status = unquote(request.GET["status_in"]) q = q.filter(status__in=status.split(",")) return q.annotate( plannedshort=RawSQL("quantity - plannedquantity", [])) rows = ( GridFieldText( "name", title=_("name"), key=True, formatter="detail", extra='"role":"input/demand"', ), GridFieldHierarchicalText( "item", title=_("item"), field_name="item__name", formatter="detail", extra='"role":"input/item"', model=Item, ), GridFieldText("batch", title=_("batch"), initially_hidden=True), GridFieldHierarchicalText( "location", title=_("location"), field_name="location__name", formatter="detail", extra='"role":"input/location"', model=Location, ), GridFieldHierarchicalText( "customer", title=_("customer"), field_name="customer__name", formatter="detail", extra='"role":"input/customer"', model=Customer, ), GridFieldChoice("status", title=_("status"), choices=Demand.demandstatus), GridFieldNumber("quantity", title=_("quantity")), GridFieldDateTime("due", title=_("due")), GridFieldDuration("delay", title=_("delay"), editable=False, extra='"formatter":delayfmt'), GridFieldNumber( "plannedquantity", title=_("planned quantity"), editable=False, extra= '"formatoptions":{"defaultValue":""}, "cellattr":plannedquantitycellattr', ), GridFieldNumber( "plannedshort", title=_("quantity planned short"), editable=False, extra= '"formatoptions":{"defaultValue":""}, "cellattr":plannedquantitycellattr', ), GridFieldDateTime("deliverydate", title=_("delivery date"), editable=False), GridFieldText("description", title=_("description"), initially_hidden=True), GridFieldText("category", title=_("category"), initially_hidden=True), GridFieldText("subcategory", title=_("subcategory"), initially_hidden=True), GridFieldText( "operation", title=_("delivery operation"), field_name="operation__name", formatter="detail", extra='"role":"input/operation"', initially_hidden=True, ), GridFieldInteger("priority", title=_("priority")), GridFieldText( "owner", title=_("owner"), field_name="owner__name", formatter="detail", extra='"role":"input/demand"', initially_hidden=True, ), GridFieldDuration("maxlateness", title=_("maximum lateness"), initially_hidden=True), GridFieldNumber("minshipment", title=_("minimum shipment"), initially_hidden=True), GridFieldText("batch", title=_("batch"), field_name="batch", initially_hidden=True), GridFieldText("source", title=_("source"), initially_hidden=True), GridFieldLastModified("lastmodified"), # Optional fields referencing the item GridFieldText( "item__type", title=format_lazy("{} - {}", _("item"), _("type")), initially_hidden=True, editable=False, ), GridFieldText( "item__description", title=format_lazy("{} - {}", _("item"), _("description")), 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, ), GridFieldText( "item__owner", title=format_lazy("{} - {}", _("item"), _("owner")), field_name="item__owner__name", initially_hidden=True, editable=False, formatter="detail", extra='"role":"input/item"', ), GridFieldCurrency( "item__cost", title=format_lazy("{} - {}", _("item"), _("cost")), initially_hidden=True, editable=False, ), GridFieldNumber( "item__volume", title=format_lazy("{} - {}", _("item"), _("volume")), initially_hidden=True, editable=False, ), GridFieldNumber( "item__weight", title=format_lazy("{} - {}", _("item"), _("weight")), initially_hidden=True, editable=False, ), GridFieldInteger( "item__periodofcover", title=format_lazy("{} - {}", _("item"), _("period of cover")), 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="location__available__name", formatter="detail", extra='"role":"input/calendar"', editable=False, ), GridFieldText( "location__owner", title=format_lazy("{} - {}", _("location"), _("owner")), initially_hidden=True, field_name="location__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, ), # Optional fields referencing the customer GridFieldText( "customer__description", title=format_lazy("{} - {}", _("customer"), _("description")), initially_hidden=True, editable=False, ), GridFieldText( "customer__category", title=format_lazy("{} - {}", _("customer"), _("category")), initially_hidden=True, editable=False, ), GridFieldText( "customer__subcategory", title=format_lazy("{} - {}", _("customer"), _("subcategory")), initially_hidden=True, editable=False, ), GridFieldText( "customer__owner", title=format_lazy("{} - {}", _("customer"), _("owner")), initially_hidden=True, field_name="customer__owner__name", formatter="detail", extra='"role":"input/customer"', editable=False, ), GridFieldText( "customer__source", title=format_lazy("{} - {}", _("customer"), _("source")), initially_hidden=True, editable=False, ), GridFieldLastModified( "customer__lastmodified", title=format_lazy("{} - {}", _("customer"), _("last modified")), initially_hidden=True, editable=False, ), ) if settings.ERP_CONNECTOR: actions = [{ "name": "erp_incr_export", "label": format_lazy("export to {erp}", erp=settings.ERP_CONNECTOR), "function": "ERPconnection.SODepExport(jQuery('#grid'),'SO')", }] else: actions = [ { "name": "inquiry", "label": format_lazy(_("change status to {status}"), status=_("inquiry")), "function": "grid.setStatus('inquiry')", }, { "name": "quote", "label": format_lazy(_("change status to {status}"), status=_("quote")), "function": "grid.setStatus('quote')", }, { "name": "open", "label": format_lazy(_("change status to {status}"), status=_("open")), "function": "grid.setStatus('open')", }, { "name": "closed", "label": format_lazy(_("change status to {status}"), status=_("closed")), "function": "grid.setStatus('closed')", }, { "name": "canceled", "label": format_lazy(_("change status to {status}"), status=_("canceled")), "function": "grid.setStatus('canceled')", }, ]
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' detail_post_title = _('constrained demand') detailmodel = None rows = ( #. Translators: Translation included with Django 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] and reportclass.detailmodel: request.session['lasttab'] = 'constraint' return { 'active_tab': 'constraint', 'title': force_text(reportclass.detailmodel._meta.verbose_name) + " " + args[0], 'post_title': reportclass.detail_post_title } else: return {'active_tab': 'constraint'}
class TaskReport(GridReport): ''' A list report to review the history of actions. ''' template = 'execute/execute.html' title = _('Task status') basequeryset = Task.objects.all() model = Task frozenColumns = 0 multiselect = False editable = False height = 150 default_sort = (0, 'desc') rows = ( GridFieldInteger('id', title=_('identifier'), key=True), #. Translators: Translation included with Django GridFieldText('name', title=_('name'), editable=False, align='center'), GridFieldDateTime('submitted', title=_('submitted'), editable=False, align='center'), GridFieldDateTime('started', title=_('started'), editable=False, align='center'), GridFieldDateTime('finished', title=_('finished'), editable=False, align='center'), GridFieldText('status', title=_('status'), editable=False, align='center', extra="formatter:status"), GridFieldText('message', title=_('message'), editable=False, width=500), GridFieldText('arguments', title=_('arguments'), editable=False), #. Translators: Translation included with Django GridFieldText('user', title=_('user'), field_name='user__username', editable=False, align='center'), ) @classmethod def extra_context(reportclass, request, *args, **kwargs): try: constraint = int(request.session['constraint']) except: constraint = 15 # Synchronize the scenario table with the settings Scenario.syncWithSettings() # Loop over all fixtures of all apps and directories fixtures = set() folders = list(settings.FIXTURE_DIRS) for app in get_apps(): if app.__name__.startswith('django'): continue folders.append( os.path.join(os.path.dirname(app.__file__), 'fixtures')) for f in folders: try: for root, dirs, files in os.walk(f): for i in files: if i.endswith('.json'): fixtures.add(i.split('.')[0]) except: pass # Silently ignore failures fixtures = sorted(fixtures) # Send to template odoo = 'freppledb.odoo' in settings.INSTALLED_APPS return { 'capacityconstrained': constraint & 4, 'materialconstrained': constraint & 2, 'leadtimeconstrained': constraint & 1, 'fenceconstrained': constraint & 8, 'scenarios': Scenario.objects.all(), 'fixtures': fixtures, 'openbravo': 'freppledb.openbravo' in settings.INSTALLED_APPS, 'odoo': odoo, 'odoo_read': odoo and request.session.get('odoo_read', False), 'odoo_write': odoo and request.session.get('odoo_write', False) }
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]: base = FlowPlan.objects.filter(thebuffer__exact=args[0]) else: base = FlowPlan.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_flowplan.operationplan_id " "group by demand order by 1 desc, 2) peg" % string_agg()) }) @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), GridFieldNumber('operationplan__criticality', title=_('criticality'), editable=False), GridFieldBool('operationplan__locked', title=_('locked'), editable=False), GridFieldNumber('operationplan__quantity', title=_('operationplan quantity'), editable=False), GridFieldText('demand', title=_('demand quantity'), formatter='demanddetail', width=300, editable=False), GridFieldInteger('operationplan', title=_('operationplan'), editable=False), )
class DetailReport(GridReport): ''' A list report to show OperationPlanMaterial. ''' template = 'input/operationplanreport.html' title = _("Inventory detail report") model = OperationPlanMaterial permissions = (('view_inventory_report', 'Can view inventory report'),) frozenColumns = 0 editable = False multiselect = False height = 250 help_url = 'user-guide/user-interface/plan-analysis/inventory-detail-report.html' @ classmethod def basequeryset(reportclass, request, *args, **kwargs): if len(args) and args[0]: dlmtr = args[0].find(" @ ") base = OperationPlanMaterial.objects.filter( item=args[0][:dlmtr], location=args[0][dlmtr + 3:] ) else: base = OperationPlanMaterial.objects return base.select_related().extra(select={ 'pegging': "(select string_agg(value || ' : ' || key, ', ') from (select key, value from jsonb_each_text(plan->'pegging') 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', 'model': Buffer, 'title': force_text(Buffer._meta.verbose_name) + " " + args[0], 'post_title': _('plan detail') } else: return {'active_tab': 'plandetail', 'model': None} rows = ( #. Translators: Translation included with Django GridFieldInteger('id', title=_('internal id'), key=True, editable=False, hidden=True), GridFieldText('item', title=_('item'), field_name='item__name', editable=False, formatter='detail', extra='"role":"input/item"'), GridFieldText('location', title=_('location'), field_name='location__name', editable=False, formatter='detail', extra='"role":"input/location"'), GridFieldInteger('operationplan__id', title=_('identifier'), editable=False), GridFieldText('operationplan__reference', title=_('reference'), editable=False), GridFieldText('operationplan__color', title=_('inventory status'), formatter='color', width='125', editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"'), GridFieldText('operationplan__type', title=_('type'), field_name='operationplan__type', editable=False), GridFieldText('operationplan__name', title=_('operation'), editable=False, field_name='operationplan__name', formatter='detail', extra='"role":"input/operation"'), GridFieldText('operationplan__operation__description', title=string_concat(_('operation'), ' - ', _('description')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__category', title=string_concat(_('operation'), ' - ', _('category')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__subcategory', title=string_concat(_('operation'), ' - ', _('subcategory')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__type', title=string_concat(_('operation'), ' - ', _('type')), initially_hidden=True), GridFieldDuration('operationplan__operation__duration', title=string_concat(_('operation'), ' - ', _('duration')), initially_hidden=True), GridFieldDuration('operationplan__operation__duration_per', title=string_concat(_('operation'), ' - ', _('duration per unit')), initially_hidden=True), GridFieldDuration('operationplan__operation__fence', title=string_concat(_('operation'), ' - ', _('release fence')), initially_hidden=True), GridFieldDuration('operationplan__operation__posttime', title=string_concat(_('operation'), ' - ', _('post-op time')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizeminimum', title=string_concat(_('operation'), ' - ', _('size minimum')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizemultiple', title=string_concat(_('operation'), ' - ', _('size multiple')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizemaximum', title=string_concat(_('operation'), ' - ', _('size maximum')), initially_hidden=True), GridFieldInteger('operationplan__operation__priority', title=string_concat(_('operation'), ' - ', _('priority')), initially_hidden=True), GridFieldDateTime('operationplan__operation__effective_start', title=string_concat(_('operation'), ' - ', _('effective start')), initially_hidden=True), GridFieldDateTime('operationplan__operation__effective_end', title=string_concat(_('operation'), ' - ', _('effective end')), initially_hidden=True), GridFieldCurrency('operationplan__operation__cost', title=string_concat(_('operation'), ' - ', _('cost')), initially_hidden=True), GridFieldText('operationplan__operation__search', title=string_concat(_('operation'), ' - ', _('search mode')), initially_hidden=True), GridFieldText('operationplan__operation__source', title=string_concat(_('operation'), ' - ', _('source')), initially_hidden=True), GridFieldLastModified('operationplan__operation__lastmodified', title=string_concat(_('operation'), ' - ', _('last modified')), initially_hidden=True), GridFieldDateTime('flowdate', title=_('date'), editable=False, extra='"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"min"'), GridFieldNumber('quantity', title=_('quantity'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldNumber('onhand', title=_('expected onhand'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldText('operationplan__status', title=_('status'), editable=False, field_name='operationplan__status'), GridFieldNumber('operationplan__criticality', title=_('criticality'), field_name='operationplan__criticality', editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"'), GridFieldDuration('operationplan__delay', title=_('delay'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"'), GridFieldNumber('operationplan__quantity', title=_('operationplan quantity'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldText('pegging', title=_('demands'), formatter='demanddetail', extra='"role":"input/demand"', width=300, editable=False, sortable=False), # Optional fields referencing the item GridFieldText('item__description', title=string_concat(_('item'), ' - ', _('description')), initially_hidden=True, editable=False), GridFieldText('item__category', title=string_concat(_('item'), ' - ', _('category')), initially_hidden=True, editable=False), GridFieldText('item__subcategory', title=string_concat(_('item'), ' - ', _('subcategory')), initially_hidden=True, editable=False), GridFieldText('item__owner', title=string_concat(_('item'), ' - ', _('owner')), field_name='item__owner__name', initially_hidden=True, editable=False), GridFieldText('item__source', title=string_concat(_('item'), ' - ', _('source')), initially_hidden=True, editable=False), GridFieldLastModified('item__lastmodified', title=string_concat(_('item'), ' - ', _('last modified')), initially_hidden=True, editable=False), # Optional fields referencing the location GridFieldText('location__description', title=string_concat(_('location'), ' - ', _('description')), initially_hidden=True, editable=False), GridFieldText('location__category', title=string_concat(_('location'), ' - ', _('category')), initially_hidden=True, editable=False), GridFieldText('location__subcategory', title=string_concat(_('location'), ' - ', _('subcategory')), initially_hidden=True, editable=False), GridFieldText('location__available', title=string_concat(_('location'), ' - ', _('available')), initially_hidden=True, field_name='location__available__name', formatter='detail', extra='"role":"input/calendar"', editable=False), GridFieldText('location__owner', title=string_concat(_('location'), ' - ', _('owner')), initially_hidden=True, field_name='location__owner__name', formatter='detail', extra='"role":"input/location"', editable=False), GridFieldText('location__source', title=string_concat(_('location'), ' - ', _('source')), initially_hidden=True, editable=False), GridFieldLastModified('location__lastmodified', title=string_concat(_('location'), ' - ', _('last modified')), initially_hidden=True, editable=False), )
class OverviewReport(GridPivot): ''' A report showing the planned starts of each operation. ''' template = 'output/operation.html' title = _('Operation report') model = Operation permissions = (("view_operation_report", "Can view operation report"),) help_url = 'user-guide/user-interface/plan-analysis/operation-report.html' rows = ( GridFieldText( 'operation', title=_('operation'), key=True, editable=False, field_name='name', formatter='detail', extra='"role":"input/operation"' ), GridFieldText( 'location', title=_('location'), editable=False, field_name='location__name', formatter='detail', extra='"role":"input/location"' ), # Optional fields on the operation GridFieldText( 'item', title=_('item'), editable=False, field_name="item__name", formatter='detail', extra='"role":"input/item"', initially_hidden=True ), GridFieldText( 'description', title=_('description'), editable=False, initially_hidden=True ), GridFieldText( 'category', title=_('category'), editable=False, initially_hidden=True ), GridFieldText( 'subcategory', title=_('subcategory'), editable=False, initially_hidden=True ), GridFieldText( 'type', title=_('type'), initially_hidden=True, editable=False ), GridFieldDuration( 'duration', title=_('duration'), initially_hidden=True, editable=False ), GridFieldDuration( 'duration_per', title=_('duration per unit'), initially_hidden=True, editable=False ), GridFieldDuration( 'fence', title=_('release fence'), initially_hidden=True, editable=False ), GridFieldDuration( 'posttime', title=_('post-op time'), initially_hidden=True, editable=False ), GridFieldNumber( 'sizeminimum', title=_('size minimum'), initially_hidden=True, editable=False ), GridFieldNumber( 'sizemultiple', title=_('size multiple'), initially_hidden=True, editable=False ), GridFieldNumber( 'sizemaximum', title=_('size maximum'), initially_hidden=True, editable=False ), GridFieldInteger( 'priority', title=_('priority'), initially_hidden=True, editable=False ), GridFieldDateTime( 'effective_start', title=_('effective start'), initially_hidden=True, editable=False ), GridFieldDateTime( 'effective_end', title=_('effective end'), initially_hidden=True, editable=False ), GridFieldCurrency( 'cost', title=_('cost'), initially_hidden=True, editable=False ), GridFieldText( 'search', title=_('search mode'), initially_hidden=True, editable=False ), GridFieldText( 'source', title=_('source'), initially_hidden=True, editable=False ), GridFieldLastModified( 'lastmodified', initially_hidden=True, editable=False ), # Optional fields on the location GridFieldText( 'location__description', editable=False, initially_hidden=True, title=string_concat(_('location'), ' - ', _('description')) ), GridFieldText( 'location__category', editable=False, initially_hidden=True, title=string_concat(_('location'), ' - ', _('category')) ), GridFieldText( 'location__subcategory', editable=False, initially_hidden=True, title=string_concat(_('location'), ' - ', _('subcategory')) ), GridFieldText( 'location__available', editable=False, initially_hidden=True, title=string_concat(_('location'), ' - ', _('available')), field_name='location__available__name', formatter='detail', extra='"role":"input/calendar"' ), GridFieldLastModified( 'location__lastmodified', initially_hidden=True, editable=False, title=string_concat(_('location'), ' - ', _('last modified')) ), # Optional fields referencing the item GridFieldText( 'item__description', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('description')) ), GridFieldText( 'item__category', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('category')) ), GridFieldText( 'item__subcategory', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('subcategory')) ), GridFieldText( 'item__owner', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('owner')), field_name='item__owner__name' ), GridFieldText( 'item__source', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('source')) ), GridFieldLastModified( 'item__lastmodified', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('last modified')) ), ) crosses = ( ('proposed_start', {'title': _('proposed starts')}), ('total_start', {'title': _('total starts')}), ('proposed_end', {'title': _('proposed ends')}), ('total_end', {'title': _('total ends')}), ('production_proposed', {'title': _('proposed production')}), ('production_total', {'title': _('total production')}), ) @staticmethod def basequeryset(request, args, kwargs): if args and args[0]: request.session['lasttab'] = 'plan' return Operation.objects.all() else: current, start, end = getHorizon(request) return Operation.objects.all().extra( where=['exists (select 1 from operationplan where operationplan.operation_id = operation.name and startdate <= %s and enddate >= %s)'], params=[end, start] ) @staticmethod def extra_context(request, *args, **kwargs): if args and args[0]: request.session['lasttab'] = 'plan' return { 'title': force_text(Operation._meta.verbose_name) + " " + args[0], 'post_title': _('plan') } else: return {} @staticmethod def query(request, basequery, sortsql='1 asc'): basesql, baseparams = basequery.query.get_compiler(basequery.db).as_sql(with_col_aliases=False) # Run the query cursor = connections[request.database].cursor() query = ''' select operation.name, location.name, operation.item_id, operation.description, operation.category, operation.subcategory, operation.type, operation.duration, operation.duration_per, operation.fence, operation.posttime, operation.sizeminimum, operation.sizemultiple, operation.sizemaximum, operation.priority, operation.effective_start, operation.effective_end, operation.cost, operation.search, operation.source, operation.lastmodified, location.description, location.category, location.subcategory, location.available_id, location.lastmodified, item.description, item.category, item.subcategory, item.owner_id, item.source, item.lastmodified, res.bucket, res.startdate, res.enddate, res.proposed_start, res.total_start, res.proposed_end, res.total_end, res.proposed_production, res.total_production from operation left outer join item on operation.item_id = item.name left outer join location on operation.location_id = location.name inner join ( select oper.name as operation_id, d.bucket, d.startdate, d.enddate, coalesce(sum( case when operationplan.status = 'proposed' and d.startdate <= operationplan.startdate and d.enddate > operationplan.startdate then operationplan.quantity else 0 end ), 0) proposed_start, coalesce(sum( case when d.startdate <= operationplan.startdate and d.enddate > operationplan.startdate then operationplan.quantity else 0 end ), 0) total_start, coalesce(sum( case when operationplan.status = 'proposed' and d.startdate < operationplan.enddate and d.enddate >= operationplan.enddate then operationplan.quantity else 0 end ), 0) proposed_end, coalesce(sum( case when d.startdate < operationplan.enddate and d.enddate >= operationplan.enddate then operationplan.quantity else 0 end ), 0) total_end, coalesce(sum( case when operationplan.status = 'proposed' then ( -- Total overlap extract (epoch from least(operationplan.enddate, d.enddate) - greatest(operationplan.startdate, d.startdate)) -- Minus the interruptions - coalesce(( select sum(greatest(0, extract (epoch from least(to_timestamp(value->>1, 'YYYY-MM-DD HH24:MI:SS'), d.enddate) - greatest(to_timestamp(value->>0, 'YYYY-MM-DD HH24:MI:SS'), d.startdate) ))) from ( select * from jsonb_array_elements(plan->'interruptions')) breaks ), 0) ) / greatest(1, extract(epoch from operationplan.enddate - operationplan.startdate) - coalesce((plan#>>'{unavailable}')::numeric, 0)) * operationplan.quantity else 0 end ), 0) proposed_production, coalesce(sum( ( -- Total overlap extract (epoch from least(operationplan.enddate, d.enddate) - greatest(operationplan.startdate, d.startdate)) -- Minus the interruptions - coalesce(( select sum(greatest(0, extract (epoch from least(to_timestamp(value->>1, 'YYYY-MM-DD HH24:MI:SS'), d.enddate) - greatest(to_timestamp(value->>0, 'YYYY-MM-DD HH24:MI:SS'), d.startdate) ))) from ( select * from jsonb_array_elements(plan->'interruptions')) breaks ), 0) ) / greatest(1, extract(epoch from operationplan.enddate - operationplan.startdate) - coalesce((plan#>>'{unavailable}')::numeric, 0)) * operationplan.quantity ), 0) total_production from (%s) oper -- 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 -- Match overlapping operationplans left outer join operationplan on operationplan.operation_id = oper.name and (operationplan.startdate, operationplan.enddate) overlaps (d.startdate, d.enddate) group by oper.name, d.bucket, d.startdate, d.enddate ) res on res.operation_id = operation.name order by %s, res.startdate ''' % ( basesql, request.report_bucket, request.report_startdate, request.report_enddate, sortsql ) cursor.execute(query, baseparams) # Convert the SQl results to Python for row in cursor.fetchall(): yield { 'operation': row[0], 'location': row[1], 'item': row[2], 'description': row[3], 'category': row[4], 'subcategory': row[5], 'type': row[6], 'duration': row[7], 'duration_per': row[8], 'fence': row[9], 'posttime': row[10], 'sizeminimum': row[11], 'sizemultiple': row[12], 'sizemaximum': row[13], 'priority': row[14], 'effective_start': row[15], 'effective_end': row[16], 'cost': row[17], 'search': row[18], 'source': row[19], 'lastmodified': row[20], 'location__description': row[21], 'location__category': row[22], 'location__subcategory': row[23], 'location__available': row[24], 'location__lastmodified': row[25], 'item__description': row[26], 'item__category': row[27], 'item__subcategory': row[28], 'item__owner': row[29], 'item__source': row[30], 'item__lastmodified': row[31], 'bucket': row[32], 'startdate': row[33].date(), 'enddate': row[34].date(), 'proposed_start': row[35], 'total_start': row[36], 'proposed_end': row[37], 'total_end': row[38], 'production_proposed': row[39], 'production_total': row[40] }
class Report(GridReport): title = _("Performance Indicators") frozenColumns = 0 basequeryset = Parameter.objects.all() permissions = (("view_kpi_report", "Can view kpi report"), ) rows = ( GridFieldText( "category", title=_("category"), sortable=False, editable=False, align="center", ), GridFieldText("name", title=_("name"), sortable=False, editable=False, align="center"), GridFieldInteger("value", title=_("value"), sortable=False, editable=False, align="center"), ) default_sort = (1, "asc") filterable = False multiselect = False help_url = ( "user-guide/user-interface/plan-analysis/performance-indicator-report.html" ) @staticmethod def query(request, basequery): # Execute the query cursor = connections[request.database].cursor() cursor.execute(""" select 101 as id, 'Problem count' as category, name as name, count(*) as value from out_problem group by name union all select 102, 'Problem weight', name, round(sum(weight)) from out_problem group by name union all select 201, 'Demand', 'Requested', coalesce(round(sum(quantity)),0) from demand where status in ('open', 'quote') union all select 202, 'Demand', 'Planned', coalesce(round(sum(quantity)),0) from operationplan where demand_id is not null and owner_id is null union all select 203, 'Demand', 'Planned late', coalesce(round(sum(quantity)),0) from operationplan where enddate > due and demand_id is not null and owner_id is null union all select 204, 'Demand', 'Planned on time', coalesce(round(sum(quantity)),0) from operationplan where enddate <= due and demand_id is not null and owner_id is null union all select 205, 'Demand', 'Unplanned', coalesce(round(sum(weight)),0) from out_problem where name = 'unplanned' union all select 206, 'Demand', 'Total lateness', coalesce(round(sum(quantity * extract(epoch from enddate - due)) / 86400),0) from operationplan where enddate > due and demand_id is not null and owner_id is null union all select 301, 'Operation', 'Count', count(*) from operationplan union all select 301, 'Operation', 'Quantity', coalesce(round(sum(quantity)),0) from operationplan union all select 302, 'Resource', 'Usage', coalesce(round(sum(quantity * extract(epoch from enddate - startdate)) / 86400),0) from operationplanresource union all select 401, 'Material', 'Produced', coalesce(round(sum(quantity)),0) from operationplanmaterial where quantity>0 union all select 402, 'Material', 'Consumed', coalesce(round(sum(-quantity)),0) from operationplanmaterial where quantity<0 order by 1 """) # Build the python result for row in cursor.fetchall(): yield {"category": row[1], "name": row[2], "value": row[3]}
class OverviewReport(GridPivot): """ A report showing the independent demand for each item. """ template = "output/demand.html" title = _("Demand report") post_title = _("plan") basequeryset = Item.objects.all() model = Item permissions = (("view_demand_report", "Can view demand report"),) rows = ( GridFieldText( "item", title=_("item"), key=True, editable=False, field_name="name", formatter="detail", extra='"role":"input/item"', ), GridFieldText("description", title=_("description"), initially_hidden=True), 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"', initially_hidden=True, ), GridFieldCurrency("cost", title=_("cost"), initially_hidden=True), GridFieldNumber("volume", title=_("volume"), initially_hidden=True), GridFieldNumber("weight", title=_("weight"), initially_hidden=True), GridFieldText("uom", title=_("unit of measure"), initially_hidden=True), GridFieldInteger( "periodofcover", title=_("period of cover"), initially_hidden=True ), GridFieldText("source", title=_("source"), initially_hidden=True), GridFieldLastModified("lastmodified", initially_hidden=True), ) crosses = ( ("demand", {"title": _("sales orders")}), ("supply", {"title": _("supply")}), ("backlog", {"title": _("backlog")}), ("reasons", {"title": _("reasons"), "visible": False}), ) help_url = "user-interface/plan-analysis/demand-report.html" @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, initially_hidden=False): f.editable = False reportclass.rows += (f,) reportclass.attr_sql += "parent.%s, " % f.name.split("__")[-1] @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session["lasttab"] = "plan" return { "title": force_str(Item._meta.verbose_name) + " " + args[0], "post_title": _("plan"), "model": Item, } 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 ) # Assure the item hierarchy is up to date Item.rebuildHierarchy(database=basequery.db) # Execute a query to get the backlog at the start of the horizon startbacklogdict = {} query = """ select name, sum(qty) from ( select item.name, sum(demand.quantity) qty from (%s) item inner join item child on child.lft between item.lft and item.rght inner join demand on demand.item_id = child.name and demand.status in ('open','quote') and due < %%s group by item.name union all select item.name, sum(operationplanmaterial.quantity) qty from (%s) item inner join item child on child.lft between item.lft and item.rght inner join operationplanmaterial on operationplanmaterial.item_id = child.name inner join operationplan on operationplan.reference = operationplanmaterial.operationplan_id and operationplan.demand_id is not null and operationplan.enddate < %%s group by item.name ) t group by name """ % ( basesql, basesql, ) with transaction.atomic(using=request.database): with connections[request.database].chunked_cursor() as cursor_chunked: cursor_chunked.execute( query, baseparams + (request.report_startdate,) + baseparams + (request.report_startdate,), ) for row in cursor_chunked: if row[0]: startbacklogdict[row[0]] = max(float(row[1]), 0) # Execute the query query = """ select parent.name, parent.description, parent.category, parent.subcategory, parent.owner_id, parent.cost, parent.volume, parent.weight, parent.uom, parent.periodofcover, parent.source, parent.lastmodified, %s d.bucket, d.startdate, d.enddate, sum(coalesce(( select sum(quantity) from demand inner join item child on child.lft between parent.lft and parent.rght where demand.item_id = child.name and status in ('open','quote') and due >= greatest(%%s,d.startdate) and due < d.enddate ),0)) orders, sum(coalesce(( select sum(operationplan.quantity) from operationplan inner join item child on child.lft between parent.lft and parent.rght where operationplan.item_id = child.name and operationplan.demand_id is not null and operationplan.enddate >= greatest(%%s,d.startdate) and operationplan.enddate < d.enddate ),0)) planned, (select json_agg(json_build_array(f1,f2)) from (select distinct out_constraint.name as f1, out_constraint.owner as f2 from out_constraint inner join item child on child.lft between parent.lft and parent.rght inner join operationplan on operationplan.demand_id = out_constraint.demand and operationplan.due is not null and out_constraint.item = child.name and operationplan.enddate >= greatest(%%s,d.startdate) and ( out_constraint.name not in ('before current', 'before fence') or out_constraint.enddate > d.enddate ) and operationplan.due < d.enddate limit 20 ) cte_reasons ) reasons from (%s) parent cross join ( select name as bucket, startdate, enddate from common_bucketdetail where bucket_id = %%s and enddate > %%s and startdate < %%s ) d group by parent.name, parent.description, parent.category, parent.subcategory, parent.owner_id, parent.cost, parent.volume, parent.weight, parent.uom, parent.periodofcover, parent.source, parent.lastmodified, parent.lft, parent.rght, %s d.bucket, d.startdate, d.enddate order by %s, d.startdate """ % ( reportclass.attr_sql, basesql, reportclass.attr_sql, sortsql, ) # Build the python result with transaction.atomic(using=request.database): with connections[request.database].chunked_cursor() as cursor_chunked: cursor_chunked.execute( query, (request.report_startdate,) * 3 # orders + planned + constraints + baseparams # orders planned + ( request.report_bucket, request.report_startdate, request.report_enddate, ), # buckets ) previtem = None itemattributefields = getAttributeFields(Item) for row in cursor_chunked: numfields = len(row) if row[0] != previtem: backlog = startbacklogdict.get(row[0], 0) previtem = row[0] backlog += float(row[numfields - 3]) - float(row[numfields - 2]) res = { "item": row[0], "description": row[1], "category": row[2], "subcategory": row[3], "owner": row[4], "cost": row[5], "volume": row[6], "weight": row[7], "uom": row[8], "periodofcover": row[9], "source": row[10], "lastmodified": row[11], "bucket": row[numfields - 6], "startdate": row[numfields - 5].date(), "enddate": row[numfields - 4].date(), "demand": row[numfields - 3], "supply": row[numfields - 2], "reasons": json.dumps(row[numfields - 1]), "backlog": max(backlog or 0, 0), } idx = 12 for f in itemattributefields: res[f.field_name] = row[idx] idx += 1 yield res
class TaskReport(GridReport): """ A list report to review the history of actions. """ template = "execute/execute.html" title = _("Task status") basequeryset = (Task.objects.all().extra( select={ "duration": "case when status in ('Done', '100%%') then finished::timestamp(0) - started::timestamp(0) end" }).select_related("user")) model = Task frozenColumns = 0 multiselect = False editable = False height = 150 default_sort = (0, "desc") help_url = "user-interface/execute.html" rows = ( GridFieldInteger("id", title=_("identifier"), key=True), GridFieldText("name", title=_("name"), editable=False, align="center"), GridFieldLocalDateTime("submitted", title=_("submitted"), editable=False, align="center"), GridFieldLocalDateTime("started", title=_("started"), editable=False, align="center"), GridFieldLocalDateTime("finished", title=_("finished"), editable=False, align="center"), GridFieldText( "status", title=_("status"), editable=False, align="center", extra="formatter:status", ), GridFieldText( "logfile", title=_("log file"), width=80, editable=False, align="center", extra="formatter:logbutton", ), GridFieldText( "message", title=_("message"), editable=False, width=500, formatter="longstring", ), GridFieldText("arguments", title=_("arguments"), formatter="longstring", editable=False), GridFieldText( "user", title=_("user"), field_name="user__username", editable=False, align="center", ), GridFieldDuration( "duration", title=_("duration"), search=False, editable=False, align="center", ), GridFieldBool("cancelable", title="cancelable", hidden=True), ) @classmethod def extra_context(reportclass, request, *args, **kwargs): # Loop over all accordion of all apps and directories accordions = set() accord = "" for commandname, appname in get_commands().items(): try: accord = getattr( import_module("%s.management.commands.%s" % (appname, commandname)), "Command", ) if getattr(accord, "index", -1) >= 0 and getattr( accord, "getHTML", None): accordions.add(accord) except Exception as e: logger.warning( "Couldn't import getHTML method from %s.management.commands.%s: %s" % (appname, commandname, e)) accordions = sorted(accordions, key=operator.attrgetter("index")) # Send to template return {"commandlist": accordions} @classmethod def query(reportclass, request, basequery, sortsql="1 asc"): logfileslist = set([ x for x in os.listdir(settings.FREPPLE_LOGDIR) if x.endswith(".log") or (x.lower().endswith( ".dump") and request.user.username in settings.SUPPORT_USERS) ]) for rec in basequery: yield { "id": rec.id, "name": rec.name, "submitted": rec.submitted, "started": rec.started, "finished": rec.finished, "status": rec.status, "logfile": rec.logfile if rec.logfile in logfileslist else None, "message": rec.message, "arguments": rec.arguments, "user__username": rec.user.username if rec.user else None, "duration": rec.duration, "cancelable": rec.processid is not None or rec.status == "Waiting", } @classmethod def extraJSON(reportclass, request): try: lastCompletedTask = (Task.objects.all().using( request.database).filter( status="Done").order_by("-id").only("id")[0]) return '"lastcompleted":%d,\n' % lastCompletedTask.id except Exception: return '"lastcompleted":0,\n'
class DetailReport(GridReport): ''' A list report to show OperationPlanMaterial. ''' template = 'input/operationplanreport.html' title = _("Inventory detail report") model = OperationPlanMaterial permissions = (('view_inventory_report', 'Can view inventory report'), ) frozenColumns = 0 editable = False multiselect = False height = 250 help_url = 'user-guide/user-interface/plan-analysis/inventory-detail-report.html' @classmethod def basequeryset(reportclass, request, args, kwargs): if args and args[0]: base = OperationPlanMaterial.objects.filter(buffer__exact=args[0]) else: base = OperationPlanMaterial.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 = ( #. Translators: Translation included with Django GridFieldInteger('id', title=_('internal id'), key=True, editable=False, hidden=True), GridFieldText('buffer', title=_('buffer'), editable=False, formatter='detail', extra='"role":"input/buffer"'), GridFieldInteger('operationplan__id', title=_('identifier'), editable=False), GridFieldText('operationplan__reference', title=_('reference'), editable=False), GridFieldText('operationplan__type', title=_('type'), field_name='operationplan__type', editable=False), GridFieldText('operationplan__name', title=_('operation'), editable=False, field_name='operationplan__name', formatter='detail', extra='"role":"input/operation"'), GridFieldDateTime('flowdate', title=_('date'), editable=False), GridFieldNumber('quantity', title=_('quantity'), editable=False), GridFieldNumber('onhand', title=_('onhand'), editable=False), GridFieldText('operationplan__status', title=_('status'), editable=False, field_name='operationplan__status'), GridFieldNumber('operationplan__criticality', title=_('criticality'), field_name='operationplan__criticality', editable=False), GridFieldNumber('operationplan__quantity', title=_('operationplan quantity'), editable=False), GridFieldText('pegging', title=_('demands'), formatter='demanddetail', extra='"role":"input/demand"', width=300, editable=False, sortable=False), )
class DetailReport(OperationPlanMixin, GridReport): ''' A list report to show OperationPlanResources. ''' template = 'input/operationplanreport.html' title = _("Resource detail report") model = OperationPlanResource permissions = (("view_resource_report", "Can view resource report"), ) frozenColumns = 3 editable = False multiselect = False height = 250 help_url = 'user-guide/user-interface/plan-analysis/resource-detail-report.html' @classmethod def basequeryset(reportclass, request, *args, **kwargs): if args and args[0]: try: res = Resource.objects.using( request.database).get(name__exact=args[0]) base = OperationPlanResource.objects.filter( resource__lft__gte=res.lft, resource__rght__lte=res.rght) except OperationPlanResource.DoesNotExist: base = OperationPlanResource.objects.filter( resource__exact=args[0]) else: base = OperationPlanResource.objects base = reportclass.operationplanExtraBasequery(base, request) return base.select_related().extra( select={ 'opplan_duration': "(operationplan.enddate - operationplan.startdate)", 'opplan_net_duration': "(operationplan.enddate - operationplan.startdate - coalesce((operationplan.plan->>'unavailable')::int * interval '1 second', interval '0 second'))", 'setup_end': "(operationplan.plan->>'setupend')", 'setup_duration': "(operationplan.plan->>'setup')", 'feasible': "coalesce((operationplan.plan->>'feasible')::boolean, true)" }) @classmethod def initialize(reportclass, request): if reportclass._attributes_added != 2: reportclass._attributes_added = 2 # Adding custom operation attributes for f in getAttributeFields( Operation, related_name_prefix="operationplan__operation"): f.editable = False reportclass.rows += (f, ) # Adding custom resource attributes for f in getAttributeFields(Resource, related_name_prefix="resource"): f.editable = False reportclass.rows += (f, ) @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session['lasttab'] = 'plandetail' return { 'active_tab': 'plandetail', 'model': Resource, 'title': force_text(Resource._meta.verbose_name) + " " + args[0], 'post_title': _('plan detail') } else: return {'active_tab': 'plandetail', 'model': None} rows = ( GridFieldInteger('id', title='internal id', key=True, editable=False, hidden=True), GridFieldText('resource', title=_('resource'), field_name='resource__name', editable=False, formatter='detail', extra='"role":"input/resource"'), GridFieldInteger('operationplan__id', title=_('identifier'), editable=False), GridFieldText('operationplan__reference', title=_('reference'), editable=False), GridFieldText( 'operationplan__color', title=_('inventory status'), formatter='color', width='125', editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"'), GridFieldText('operationplan__operation__item', title=_('item'), editable=False, formatter='detail', extra='"role":"input/item"'), GridFieldText('operationplan__operation__location', title=_('location'), editable=False, formatter='detail', extra='"role":"input/location"'), GridFieldText('operationplan__operation__name', title=_('operation'), editable=False, formatter='detail', extra='"role":"input/operation"'), GridFieldText('operationplan__operation__description', title=string_concat(_('operation'), ' - ', _('description')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__category', title=string_concat(_('operation'), ' - ', _('category')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__subcategory', title=string_concat(_('operation'), ' - ', _('subcategory')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__type', title=string_concat(_('operation'), ' - ', _('type')), initially_hidden=True), GridFieldDuration('operationplan__operation__duration', title=string_concat(_('operation'), ' - ', _('duration')), initially_hidden=True), GridFieldDuration('operationplan__operation__duration_per', title=string_concat(_('operation'), ' - ', _('duration per unit')), initially_hidden=True), GridFieldDuration('operationplan__operation__fence', title=string_concat(_('operation'), ' - ', _('release fence')), initially_hidden=True), GridFieldDuration('operationplan__operation__posttime', title=string_concat(_('operation'), ' - ', _('post-op time')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizeminimum', title=string_concat(_('operation'), ' - ', _('size minimum')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizemultiple', title=string_concat(_('operation'), ' - ', _('size multiple')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizemaximum', title=string_concat(_('operation'), ' - ', _('size maximum')), initially_hidden=True), GridFieldInteger('operationplan__operation__priority', title=string_concat(_('operation'), ' - ', _('priority')), initially_hidden=True), GridFieldDateTime('operationplan__operation__effective_start', title=string_concat(_('operation'), ' - ', _('effective start')), initially_hidden=True), GridFieldDateTime('operationplan__operation__effective_end', title=string_concat(_('operation'), ' - ', _('effective end')), initially_hidden=True), GridFieldCurrency('operationplan__operation__cost', title=string_concat(_('operation'), ' - ', _('cost')), initially_hidden=True), GridFieldText('operationplan__operation__search', title=string_concat(_('operation'), ' - ', _('search mode')), initially_hidden=True), GridFieldText('operationplan__operation__source', title=string_concat(_('operation'), ' - ', _('source')), initially_hidden=True), GridFieldLastModified('operationplan__operation__lastmodified', title=string_concat(_('operation'), ' - ', _('last modified')), initially_hidden=True), GridFieldDateTime( 'operationplan__startdate', title=_('start date'), editable=False, extra= '"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"min"' ), GridFieldDateTime( 'operationplan__enddate', title=_('end date'), editable=False, extra= '"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"max"' ), GridFieldDuration( 'opplan_duration', title=_('duration'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldDuration( 'opplan_net_duration', title=_('net duration'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldNumber( 'operationplan__quantity', title=_('quantity'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldText('operationplan__status', title=_('status'), editable=False), GridFieldNumber( 'operationplan__criticality', title=_('criticality'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"'), GridFieldDuration( 'operationplan__delay', title=_('delay'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"'), GridFieldText('demand', title=_('demands'), formatter='demanddetail', extra='"role":"input/demand"', width=300, editable=False, sortable=False), GridFieldText('operationplan__type', title=_('type'), field_name='operationplan__type', editable=False), GridFieldNumber( 'quantity', title=_('load quantity'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldText('setup', title=_('setup'), editable=False, initially_hidden=True), GridFieldDateTime('setup_end', title=_('setup end date'), editable=False, initially_hidden=True), GridFieldDuration('setup_duration', title=_('setup duration'), editable=False, initially_hidden=True), GridFieldBool('feasible', title=_('feasible'), editable=False, initially_hidden=True, search=False), # Optional fields referencing the item GridFieldText('operationplan__operation__item__description', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('description'))), GridFieldText('operationplan__operation__item__category', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('category'))), GridFieldText('operationplan__operation__item__subcategory', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('subcategory'))), GridFieldText( 'operationplan__operation__item__owner', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('owner')), field_name='operationplan__operation__item__owner__name'), GridFieldText('operationplan__operation__item__source', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('source'))), GridFieldLastModified( 'operationplan__operation__item__lastmodified', initially_hidden=True, editable=False, title=string_concat(_('item'), ' - ', _('last modified')), ), # Optional fields referencing the operation location GridFieldText('operationplan__operation__location__description', initially_hidden=True, editable=False, title=string_concat(_('location'), ' - ', _('description'))), GridFieldText('operationplan__operation__location__category', title=string_concat(_('location'), ' - ', _('category')), initially_hidden=True, editable=False), GridFieldText('operationplan__operation__location__subcategory', title=string_concat(_('location'), ' - ', _('subcategory')), initially_hidden=True, editable=False), GridFieldText( 'operationplan__operation__location__available', editable=False, title=string_concat(_('location'), ' - ', _('available')), initially_hidden=True, field_name='operationplan__operation__location__available__name', formatter='detail', extra='"role":"input/calendar"'), GridFieldText( 'operationplan__operation__location__owner', initially_hidden=True, title=string_concat(_('location'), ' - ', _('owner')), field_name='operationplan__operation__location__owner__name', formatter='detail', extra='"role":"input/location"', editable=False), GridFieldText('operationplan__operation__location__source', initially_hidden=True, editable=False, title=string_concat(_('location'), ' - ', _('source'))), GridFieldLastModified( 'operationplan__operation__location__lastmodified', initially_hidden=True, editable=False, title=string_concat(_('location'), ' - ', _('last modified'))), # Optional fields referencing the resource GridFieldText('resource__description', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('description'))), GridFieldText('resource__category', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('category'))), GridFieldText('resource__subcategory', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('subcategory'))), GridFieldText('resource__type', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('type'))), GridFieldNumber('resource__maximum', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('maximum'))), GridFieldText('resource__maximum_calendar', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('maximum calendar')), field_name='resource__maximum_calendar__name', formatter='detail', extra='"role":"input/calendar"'), GridFieldCurrency('resource__cost', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('cost'))), GridFieldDuration('resource__maxearly', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('maxearly'))), GridFieldText('resource__setupmatrix', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('setupmatrix')), field_name='resource__setupmatrix__name', formatter='detail', extra='"role":"input/setupmatrix"'), GridFieldText('resource__setup', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('setup'))), GridFieldText('resource_location', editable=False, initially_hidden=True, title=string_concat(_('resource'), ' - ', _('location')), field_name='resource__location__name', formatter='detail', extra='"role":"input/location"'), # Optional fields referencing the resource location GridFieldText('resource__location__description', initially_hidden=True, editable=False, title=string_concat(_('resource'), ' - ', _('location'), ' - ', _('description'))), GridFieldText('resource__location__category', initially_hidden=True, editable=False, title=string_concat(_('resource'), ' - ', _('location'), ' - ', _('category'))), GridFieldText('resource__location__subcategory', initially_hidden=True, editable=False, title=string_concat(_('resource'), ' - ', _('location'), ' - ', _('subcategory'))), GridFieldText('resource__location__available', initially_hidden=True, editable=False, title=string_concat(_('resource'), ' - ', _('location'), ' - ', _('available')), field_name='resource__location__available__name', formatter='detail', extra='"role":"input/calendar"'), GridFieldText('resource__location__owner', extra='"role":"input/location"', editable=False, title=string_concat(_('resource'), ' - ', _('location'), ' - ', _('owner')), initially_hidden=True, field_name='resource__location__owner__name', formatter='detail'), GridFieldText('resource__location__source', initially_hidden=True, editable=False, title=string_concat(_('resource'), ' - ', _('location'), ' - ', _('source'))), GridFieldLastModified('resource__location__lastmodified', initially_hidden=True, editable=False, title=string_concat(_('resource'), ' - ', _('location'), ' - ', _('last modified'))), )
class DetailReport(GridReport): ''' A list report to show OperationPlanResources. ''' template = 'input/operationplanreport.html' title = _("Resource detail report") model = OperationPlanResource permissions = (("view_resource_report", "Can view resource report"),) frozenColumns = 3 editable = False multiselect = False height = 250 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->'pegging') order by key desc) peg)", 'duration': "(operationplan.enddate - operationplan.startdate)" }) @classmethod def initialize(reportclass, request): if reportclass._attributes_added != 2: reportclass._attributes_added = 2 # Adding custom operation attributes for f in getAttributeFields(Operation, related_name_prefix="operation"): f.editable = False reportclass.rows += (f,) # Adding custom resource attributes for f in getAttributeFields(Resource, related_name_prefix="resource"): f.editable = False reportclass.rows += (f,) @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session['lasttab'] = 'plandetail' return {'active_tab': 'plandetail', 'model': Resource} else: return {'active_tab': 'plandetail', 'model': None} rows = ( GridFieldInteger('id', title='internal id', key=True, editable=False, hidden=True), GridFieldText('resource', title=_('resource'), editable=False, formatter='detail', extra='"role":"input/resource"'), GridFieldInteger('operationplan__id', title=_('identifier'), editable=False), GridFieldText('operationplan__reference', title=_('reference'), editable=False), GridFieldText('operationplan__color', title=_('inventory status'), formatter='color', width='125', editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"'), GridFieldText('operationplan__operation__item', title=_('item'), editable=False, formatter='detail', extra='"role":"input/item"'), GridFieldText('operationplan__operation__location', title=_('location'), editable=False, formatter='detail', extra='"role":"input/location"'), GridFieldText('operationplan__operation', title=_('operation'), editable=False, formatter='detail', extra='"role":"input/operation"'), GridFieldText('operationplan__operation__description', title=string_concat(_('operation'), ' - ', _('description')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__category', title=string_concat(_('operation'), ' - ', _('category')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__subcategory', title=string_concat(_('operation'), ' - ', _('subcategory')), editable=False, initially_hidden=True), GridFieldText('operationplan__operation__type', title=string_concat(_('operation'), ' - ', _('type')), initially_hidden=True), GridFieldDuration('operationplan__operation__duration', title=string_concat(_('operation'), ' - ', _('duration')), initially_hidden=True), GridFieldDuration('operationplan__operation__duration_per', title=string_concat(_('operation'), ' - ', _('duration per unit')), initially_hidden=True), GridFieldDuration('operationplan__operation__fence', title=string_concat(_('operation'), ' - ', _('release fence')), initially_hidden=True), GridFieldDuration('operationplan__operation__posttime', title=string_concat(_('operation'), ' - ', _('post-op time')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizeminimum', title=string_concat(_('operation'), ' - ', _('size minimum')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizemultiple', title=string_concat(_('operation'), ' - ', _('size multiple')), initially_hidden=True), GridFieldNumber('operationplan__operation__sizemaximum', title=string_concat(_('operation'), ' - ', _('size maximum')), initially_hidden=True), GridFieldInteger('operationplan__operation__priority', title=string_concat(_('operation'), ' - ', _('priority')), initially_hidden=True), GridFieldDateTime('operationplan__operation__effective_start', title=string_concat(_('operation'), ' - ', _('effective start')), initially_hidden=True), GridFieldDateTime('operationplan__operation__effective_end', title=string_concat(_('operation'), ' - ', _('effective end')), initially_hidden=True), GridFieldCurrency('operationplan__operation__cost', title=string_concat(_('operation'), ' - ', _('cost')), initially_hidden=True), GridFieldText('operationplan__operation__search', title=string_concat(_('operation'), ' - ', _('search mode')), initially_hidden=True), GridFieldText('operationplan__operation__source', title=string_concat(_('operation'), ' - ', _('source')), initially_hidden=True), GridFieldLastModified('operationplan__operation__lastmodified', title=string_concat(_('operation'), ' - ', _('last modified')), initially_hidden=True), GridFieldDateTime('operationplan__startdate', title=_('start date'), editable=False, extra='"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"min"'), GridFieldDateTime('operationplan__enddate', title=_('end date'), editable=False, extra='"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"max"'), GridFieldDuration('duration', title=_('duration'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldNumber('operationplan__quantity', title=_('quantity'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldText('operationplan__status', title=_('status'), editable=False), GridFieldNumber('operationplan__criticality', title=_('criticality'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"'), GridFieldDuration('operationplan__delay', title=_('delay'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"'), GridFieldText('pegging', title=_('demands'), formatter='demanddetail', extra='"role":"input/demand"', width=300, editable=False, sortable=False), GridFieldText('operationplan__type', title=_('type'), field_name='operationplan__type', editable=False), GridFieldNumber('quantity', title=_('load quantity'), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"'), GridFieldText('setup', title=_('setup'), editable=False), )