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 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-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), )
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 = 2 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')), 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))
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 DetailReport(GridReport): ''' A list report to show flowplans. ''' template = 'output/flowplan.html' title = _("Inventory detail report") model = FlowPlan permissions = (('view_inventory_report','Can view inventory report'),) frozenColumns = 0 editable = False multiselect = False @ classmethod def basequeryset(reportclass, request, args, kwargs): if args and args[0]: return FlowPlan.objects.filter(thebuffer__exact=args[0]).extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",}) else: return FlowPlan.objects.extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",}) @classmethod def extra_context(reportclass, request, *args, **kwargs): return {'active_tab': 'plandetail'} rows = ( GridFieldText('thebuffer', title=_('buffer'), key=True, formatter='buffer', editable=False), GridFieldText('operationplan__operation', title=_('operation'), formatter='operation', editable=False), GridFieldNumber('quantity', title=_('quantity'), editable=False), GridFieldDateTime('flowdate', title=_('date'), editable=False), GridFieldNumber('onhand', title=_('onhand'), editable=False), GridFieldBool('operationplan__locked', title=_('locked'), editable=False), GridFieldInteger('operationplan', title=_('operationplan'), editable=False), )
class DetailReport(GridReport): ''' A list report to show operationplans. ''' template = 'output/operationplan.html' title = _("Operation detail report") model = OperationPlan permissions = (("view_operation_report", "Can view operation report"),) frozenColumns = 0 editable = False multiselect = False @ classmethod def basequeryset(reportclass, request, args, kwargs): if args and args[0]: return OperationPlan.objects.filter(operation__exact=args[0]).extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",}) else: return OperationPlan.objects.extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name",}) @classmethod def extra_context(reportclass, request, *args, **kwargs): return {'active_tab': 'plandetail'} rows = ( GridFieldInteger('id', title=_('operationplan'), key=True, editable=False), GridFieldText('operation', title=_('operation'), formatter='operation', editable=False), GridFieldNumber('quantity', title=_('quantity'), editable=False), GridFieldDateTime('startdate', title=_('start date'), editable=False), GridFieldDateTime('enddate', title=_('end date'), editable=False), GridFieldBool('locked', title=_('locked'), editable=False), GridFieldNumber('unavailable', title=_('unavailable'), editable=False), GridFieldInteger('owner', title=_('owner'), editable=False), )
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
def getAttributeFields(model, related_name_prefix=None, initially_hidden=False): ''' Return report fields for all attributes of a given model. ''' from freppledb.common.report import GridFieldText, GridFieldBool, GridFieldNumber from freppledb.common.report import GridFieldInteger, GridFieldDate, GridFieldDateTime from freppledb.common.report import GridFieldDuration, GridFieldTime result = [] for field_name, label, fieldtype in _register.get("%s.%s" % (model.__module__, model.__name__), []): if related_name_prefix: field_name = "%s__%s" % (related_name_prefix, field_name) label = "%s - %s" % (related_name_prefix.split('__')[-1], label) else: label = "%s - %s" % (model.__name__, label) if fieldtype == 'string': result.append( GridFieldText(field_name, title=label, initially_hidden=initially_hidden) ) elif fieldtype == 'boolean': result.append( GridFieldBool(field_name, title=label, initially_hidden=initially_hidden) ) elif fieldtype == 'number': result.append( GridFieldNumber(field_name, title=label, initially_hidden=initially_hidden) ) elif fieldtype == 'integer': result.append( GridFieldInteger(field_name, title=label, initially_hidden=initially_hidden) ) elif fieldtype == 'date': result.append( GridFieldDate(field_name, title=label, initially_hidden=initially_hidden) ) elif fieldtype == 'datetime': result.append( GridFieldDateTime(field_name, title=label, initially_hidden=initially_hidden) ) elif fieldtype == 'duration': result.append( GridFieldDuration(field_name, title=label, initially_hidden=initially_hidden) ) elif fieldtype == 'time': result.append( GridFieldTime(field_name, title=label, initially_hidden=initially_hidden) ) else: raise Exception("Invalid attribute type '%s'." % fieldtype) return result
class OperationPlanList(GridReport): ''' A list report to show operationplans. ''' template = 'input/operationplanlist.html' title = _("Operationplan List") basequeryset = OperationPlan.objects.all() model = OperationPlan frozenColumns = 1 rows = ( GridFieldInteger('id', title=_('identifier'), key=True), GridFieldText('operation', title=_('operation'), field_name='operation__name', formatter='operation'), GridFieldDateTime('startdate', title=_('start date')), GridFieldDateTime('enddate', title=_('end date')), GridFieldNumber('quantity', title=_('quantity')), GridFieldBool('locked', title=_('locked')), GridFieldInteger('owner', title=_('owner'), extra="formatoptions:{defaultValue:''}"), GridFieldText('source', title=_('source')), GridFieldLastModified('lastmodified'), )
class DetailReport(GridReport): ''' A list report to show operationplans. ''' template = 'output/operationplan.html' title = _("Operation detail report") model = OperationPlan permissions = (("view_operation_report", "Can view operation report"), ) frozenColumns = 0 editable = False multiselect = False @classmethod def basequeryset(reportclass, request, args, kwargs): if args and args[0]: base = OperationPlan.objects.filter(operation__exact=args[0]) else: base = OperationPlan.objects return base.select_related() \ .extra(select={ 'operation_in': "select name from operation where out_operationplan.operation = operation.name", 'demand': ("select %s(q || ' : ' || d, ', ') from (" "select round(sum(quantity)) as q, demand as d " "from out_demandpegging " "where out_demandpegging.operationplan = out_operationplan.id " "group by demand order by 1 desc, 2) peg" % string_agg()) }) @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session['lasttab'] = 'plandetail' return {'active_tab': 'plandetail'} rows = ( GridFieldInteger('id', title=_('operationplan'), key=True, editable=False), GridFieldText('operation', title=_('operation'), editable=False, formatter='detail', extra="role:'input/operation'"), GridFieldNumber('quantity', title=_('quantity'), editable=False), GridFieldText('demand', title=_('demand quantity'), formatter='demanddetail', extra="role:'input/demand'", width=300, editable=False), GridFieldDateTime('startdate', title=_('start date'), editable=False), GridFieldDateTime('enddate', title=_('end date'), editable=False), GridFieldNumber('criticality', title=_('criticality'), editable=False), GridFieldBool('locked', title=_('locked'), editable=False), GridFieldNumber('unavailable', title=_('unavailable'), editable=False), GridFieldInteger('owner', title=_('owner'), editable=False), )
class CalendarBucketList(GridReport): ''' A list report to show calendar buckets. ''' template = 'input/calendarbucketlist.html' title = _("Calendar Bucket List") basequeryset = CalendarBucket.objects.all() model = CalendarBucket frozenColumns = 3 rows = ( GridFieldInteger('id', title=_('identifier'), formatter='calendarbucket'), GridFieldText('calendar', title=_('calendar'), field_name='calendar__name', formatter='calendar'), GridFieldDateTime('startdate', title=_('start date')), GridFieldDateTime('enddate', title=_('end date'), editable=False), GridFieldNumber('value', title=_('value')), GridFieldInteger('priority', title=_('priority')), GridFieldBool('monday', title=_('Monday')), GridFieldBool('tuesday', title=_('Tuesday')), GridFieldBool('wednesday', title=_('Wednesday')), GridFieldBool('thursday', title=_('Thursday')), GridFieldBool('friday', title=_('Friday')), GridFieldBool('saturday', title=_('Saturday')), GridFieldBool('sunday', title=_('Sunday')), GridFieldTime('starttime', title=_('start time')), GridFieldTime('endtime', title=_('end time')), GridFieldText( 'source', title=_('source') ), # Not really right, since the engine doesn't read or store it GridFieldLastModified('lastmodified'), )
class DetailReport(GridReport): ''' A list report to show loadplans. ''' template = 'output/loadplan.html' title = _("Resource detail report") model = LoadPlan permissions = (("view_resource_report", "Can view resource report"), ) frozenColumns = 0 editable = False multiselect = False @classmethod def basequeryset(reportclass, request, args, kwargs): if args and args[0]: return LoadPlan.objects.filter(theresource__exact=args[0]).select_related() \ .extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name"}) else: return LoadPlan.objects.select_related() \ .extra(select={'operation_in': "select name from operation where out_operationplan.operation = operation.name"}) @classmethod def extra_context(reportclass, request, *args, **kwargs): return {'active_tab': 'plandetail'} rows = ( GridFieldText('theresource', title=_('resource'), key=True, formatter='resource', editable=False), GridFieldText('operationplan__operation', title=_('operation'), formatter='operation', editable=False), GridFieldDateTime('startdate', title=_('start date'), editable=False), GridFieldDateTime('enddate', title=_('end date'), editable=False), GridFieldNumber('operationplan__quantity', title=_('operationplan quantity'), editable=False), GridFieldNumber('quantity', title=_('load quantity'), editable=False), GridFieldNumber('operationplan__criticality', title=_('criticality'), editable=False), GridFieldBool('operationplan__locked', title=_('locked'), editable=False), GridFieldNumber('operationplan__unavailable', title=_('unavailable'), editable=False), GridFieldInteger('operationplan', title=_('operationplan'), editable=False), GridFieldText('setup', title=_('setup'), editable=False), )
class DetailReport(GridReport): ''' A list report to show OperationPlanResources. ''' template = 'output/loadplan.html' title = _("Resource detail report") model = OperationPlanResource permissions = (("view_resource_report", "Can view resource report"),) frozenColumns = 0 editable = False multiselect = False help_url = 'user-guide/user-interface/plan-analysis/resource-detail-report.html' @ classmethod def basequeryset(reportclass, request, args, kwargs): if args and args[0]: base = OperationPlanResource.objects.filter(resource__exact=args[0]) else: base = OperationPlanResource.objects return base.select_related().extra(select={ 'pegging': "(select string_agg(value || ' : ' || key, ', ') from (select key, value from json_each_text(plan) order by key desc) peg)" }) @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session['lasttab'] = 'plandetail' return {'active_tab': 'plandetail'} rows = ( GridFieldInteger('id', title=_('id'), key=True,editable=False, hidden=True), GridFieldText('resource', title=_('resource'), editable=False, formatter='detail', extra="role:'input/resource'"), GridFieldText('operationplan__type', title=_('type'), field_name='operationplan__type', editable=False), GridFieldText('operationplan__operation', title=_('operation'), editable=False, formatter='detail', extra="role:'input/operation'"), GridFieldDateTime('startdate', title=_('start date'), editable=False), GridFieldDateTime('enddate', title=_('end date'), editable=False), GridFieldNumber('operationplan__quantity', title=_('operationplan quantity'), editable=False), GridFieldText('pegging', title=_('demand quantity'), formatter='demanddetail', extra="role:'input/demand'", width=300, editable=False, sortable=False), GridFieldNumber('quantity', title=_('load quantity'), editable=False), GridFieldNumber('operationplan__criticality', title=_('criticality'), editable=False), GridFieldBool('operationplan__status', title=_('status'), editable=False), GridFieldText('setup', title=_('setup'), editable=False), )
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'), )
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" }) model = Task frozenColumns = 0 multiselect = False editable = False height = 150 default_sort = (0, 'desc') help_url = 'user-guide/user-interface/execute.html' 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('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'), editable=False), #. Translators: Translation included with Django 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 accord.index >= 0 and getattr(accord, 'getHTML', None): accordions.add(accord) except Exception: pass # Silently ignore failures 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') ]) 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: return '"lastcompleted":0,\n'
class PurchaseOrderList(OperationPlanMixin, GridReport): template = "input/operationplanreport.html" title = _("purchase orders") model = PurchaseOrder default_sort = (1, "desc") frozenColumns = 1 multiselect = True editable = True height = 250 help_url = "modeling-wizard/purchasing/purchase-orders.html" message_when_empty = Template( """ <h3>Define purchase orders</h3> <br> This table defines ongoing and proposed purchase orders.<br><br> Use this table to load ongoing purchase orders in the status "confirmed".<br><br> The planning algorithm will further populate this table with additional "proposed" purchase orders for the future.<br> <br><br> <div role="group" class="btn-group.btn-group-justified"> <a href="{{request.prefix}}/data/input/purchaseorder/add/" onclick="window.location = $(event.target).attr('href')" class="btn btn-primary">Create a single purchase order<br>in a form</a> <a href="{{request.prefix}}/wizard/load/production/?currentstep=7" onclick="window.location = $(event.target).attr('href')" class="btn btn-primary">Wizard to upload purchase orders<br>from a spreadsheet</a> </div> <br> """ ) calendarmode = "start_end" @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session["lasttab"] = "purchaseorders" paths = request.path.split("/") path = paths[4] if path == "supplier" or request.path.startswith("/detail/input/supplier/"): return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "purchaseorders", "model": Supplier, "title": force_text(Supplier._meta.verbose_name) + " " + args[0], "post_title": _("purchase orders"), } elif path == "location" or request.path.startswith( "/detail/input/location/" ): return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "purchaseorders", "model": Location, "title": force_text(Location._meta.verbose_name) + " " + args[0], "post_title": _("purchase orders"), } elif path == "item" or request.path.startswith("/detail/input/item/"): return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "purchaseorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": _("purchase orders"), } elif path == "operationplanmaterial": return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "purchaseorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": force_text( _("on order in %(loc)s at %(date)s") % {"loc": args[1], "date": args[2]} ), } elif path == "produced": return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "purchaseorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": force_text( _("on order in %(loc)s between %(date1)s and %(date2)s") % {"loc": args[1], "date1": args[2], "date2": args[3]} ), } else: return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "edit", "model": Item, } elif "parentreference" in request.GET: return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "edit", "title": force_text(PurchaseOrder._meta.verbose_name) + " " + request.GET["parentreference"], } else: return { "default_operationplan_type": "PO", "groupBy": "status", "active_tab": "purchaseorders", } @classmethod def basequeryset(reportclass, request, *args, **kwargs): q = PurchaseOrder.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"]) ) ) if args and args[0]: paths = request.path.split("/") path = paths[4] if paths[4] == "operationplanmaterial": q = q.filter( location__name=args[1], item__name=args[0], startdate__lt=args[2], enddate__gte=args[2], ) elif path == "produced": q = q.filter( location__name=args[1], item__name=args[0], enddate__gte=args[2], enddate__lt=args[3], ) elif path == "supplier" or request.path.startswith( "/detail/input/supplier/" ): try: Supplier.rebuildHierarchy(database=request.database) sup = ( Supplier.objects.all().using(request.database).get(name=args[0]) ) lft = sup.lft rght = sup.rght except Supplier.DoesNotExist: lft = 1 rght = 1 q = q.filter(supplier__lft__gte=lft, supplier__rght__lte=rght) elif path == "location" or request.path.startswith( "/detail/input/location/" ): try: Location.rebuildHierarchy(database=request.database) loc = ( Location.objects.all().using(request.database).get(name=args[0]) ) lft = loc.lft rght = loc.rght except Location.DoesNotExist: lft = 1 rght = 1 q = q.filter(location__lft__gte=lft, location__rght__lte=rght) elif path == "item" or request.path.startswith("/detail/input/item/"): try: Item.rebuildHierarchy(database=request.database) 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) q = reportclass.operationplanExtraBasequery(q.select_related("item"), request) return q.annotate( unit_cost=Cast( RawSQL( """ coalesce(( select cost from itemsupplier where itemsupplier.item_id = operationplan.item_id and (itemsupplier.location_id is null or itemsupplier.location_id = operationplan.location_id) and itemsupplier.supplier_id = operationplan.supplier_id order by operationplan.enddate < itemsupplier.effective_end desc nulls first, operationplan.enddate >= itemsupplier.effective_start desc nulls first, priority <> 0, priority limit 1), (select cost from item where item.name = operationplan.item_id), 0) """, [], ), output_field=FloatField(), ), total_cost=Cast(F("unit_cost") * F("quantity"), output_field=FloatField()), total_volume=Cast( F("item__volume") * F("quantity"), output_field=FloatField() ), total_weight=Cast( F("item__weight") * F("quantity"), output_field=FloatField() ), feasible=RawSQL( "coalesce((operationplan.plan->>'feasible')::boolean, true)", [] ), computed_color=RawSQL( """ case when operationplan.color >= 999999 and operationplan.plan ? 'item' then 999999 - extract(epoch from operationplan.delay)/86400.0 + 1000000 when operationplan.color >= 999999 and not(operationplan.plan ? 'item') then 999999 - extract(epoch from operationplan.delay)/86400.0 else operationplan.color end """, [], ), itemsupplier_sizeminimum=Cast( RawSQL( """ select sizeminimum from itemsupplier where itemsupplier.item_id = operationplan.item_id and (itemsupplier.location_id is null or itemsupplier.location_id = operationplan.location_id) and itemsupplier.supplier_id = operationplan.supplier_id order by operationplan.enddate < itemsupplier.effective_end desc nulls first, operationplan.enddate >= itemsupplier.effective_start desc nulls first, priority <> 0, priority limit 1 """, [], ), output_field=FloatField(), ), itemsupplier_sizemultiple=Cast( RawSQL( """ select sizemultiple from itemsupplier where itemsupplier.item_id = operationplan.item_id and (itemsupplier.location_id is null or itemsupplier.location_id = operationplan.location_id) and itemsupplier.supplier_id = operationplan.supplier_id order by operationplan.enddate < itemsupplier.effective_end desc nulls first, operationplan.enddate >= itemsupplier.effective_start desc nulls first, priority <> 0, priority limit 1 """, [], ), output_field=FloatField(), ), itemsupplier_sizemaximum=Cast( RawSQL( """ select sizemaximum from itemsupplier where itemsupplier.item_id = operationplan.item_id and (itemsupplier.location_id is null or itemsupplier.location_id = operationplan.location_id) and itemsupplier.supplier_id = operationplan.supplier_id order by operationplan.enddate < itemsupplier.effective_end desc nulls first, operationplan.enddate >= itemsupplier.effective_start desc nulls first, priority <> 0, priority limit 1 """, [], ), output_field=FloatField(), ), itemsupplier_priority=Cast( RawSQL( """ select priority from itemsupplier where itemsupplier.item_id = operationplan.item_id and (itemsupplier.location_id is null or itemsupplier.location_id = operationplan.location_id) and itemsupplier.supplier_id = operationplan.supplier_id order by operationplan.enddate < itemsupplier.effective_end desc nulls first, operationplan.enddate >= itemsupplier.effective_start desc nulls first, priority <> 0, priority limit 1 """, [], ), output_field=FloatField(), ), itemsupplier_effective_start=Cast( RawSQL( """ select effective_start from itemsupplier where itemsupplier.item_id = operationplan.item_id and (itemsupplier.location_id is null or itemsupplier.location_id = operationplan.location_id) and itemsupplier.supplier_id = operationplan.supplier_id order by operationplan.enddate < itemsupplier.effective_end desc nulls first, operationplan.enddate >= itemsupplier.effective_start desc nulls first, priority <> 0, priority limit 1 """, [], ), output_field=DateTimeField(), ), itemsupplier_effective_end=Cast( RawSQL( """ select effective_end from itemsupplier where itemsupplier.item_id = operationplan.item_id and (itemsupplier.location_id is null or itemsupplier.location_id = operationplan.location_id) and itemsupplier.supplier_id = operationplan.supplier_id order by operationplan.enddate < itemsupplier.effective_end desc nulls first, operationplan.enddate >= itemsupplier.effective_start desc nulls first, priority <> 0, priority limit 1 """, [], ), output_field=DateTimeField(), ), ) rows = ( GridFieldText( "reference", title=_("reference"), key=True, formatter="detail", extra='role:"input/purchaseorder"', editable=not settings.ERP_CONNECTOR, ), GridFieldNumber( "computed_color", title=_("inventory status"), formatter="color", width="125", editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldNumber("color", hidden=True), GridFieldHierarchicalText( "item", title=_("item"), field_name="item__name", formatter="detail", extra='"role":"input/item"', model=Item, ), GridFieldHierarchicalText( "location", title=_("location"), field_name="location__name", formatter="detail", extra='"role":"input/location"', model=Location, ), GridFieldHierarchicalText( "supplier", title=_("supplier"), field_name="supplier__name", formatter="detail", extra='"role":"input/supplier"', model=Supplier, ), GridFieldDateTime( "startdate", title=_("ordering date"), extra='"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"min"', ), GridFieldDateTime( "enddate", title=_("receipt date"), extra='"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"max"', ), GridFieldNumber( "quantity", title=_("quantity"), extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldChoice( "status", title=_("status"), choices=PurchaseOrder.orderstatus, editable=not settings.ERP_CONNECTOR, ), GridFieldCurrency( "unit_cost", title=format_lazy("{} - {}", _("item"), _("cost")), editable=False, search=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldCurrency( "total_cost", title=_("total cost"), editable=False, search=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldNumber( "total_volume", title=_("total volume"), editable=False, search=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldNumber( "total_weight", title=_("total weight"), editable=False, search=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldText( "batch", title=_("batch"), editable="true", initially_hidden=True ), GridFieldNumber( "criticality", title=_("criticality"), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldDuration( "delay", title=_("delay"), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldJSON( "demands", title=_("demands"), editable=False, search=True, sortable=False, formatter="demanddetail", extra='"role":"input/demand"', ), GridFieldText("source", title=_("source"), initially_hidden=True), GridFieldBool( "feasible", title=_("feasible"), editable=False, initially_hidden=True, search=True, ), GridFieldLastModified("lastmodified"), # Annoted fields referencing the itemsupplier GridFieldNumber( "itemsupplier_sizeminimum", title=format_lazy("{} - {}", _("item supplier"), _("size minimum")), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldNumber( "itemsupplier_sizemultiple", title=format_lazy("{} - {}", _("item supplier"), _("size multiple")), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldNumber( "itemsupplier_sizemaximum", title=format_lazy("{} - {}", _("item supplier"), _("size maximum")), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldDateTime( "itemsupplier_effective_end", title=format_lazy("{} - {}", _("item supplier"), _("effective end")), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldDateTime( "itemsupplier_effective_start", title=format_lazy("{} - {}", _("item supplier"), _("effective start")), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldNumber( "itemsupplier_priority", title=format_lazy("{} - {}", _("item supplier"), _("priority")), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), # 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, ), 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, ), 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 supplier GridFieldText( "supplier__description", title=format_lazy("{} - {}", _("supplier"), _("description")), initially_hidden=True, editable=False, ), GridFieldText( "supplier__category", title=format_lazy("{} - {}", _("supplier"), _("category")), initially_hidden=True, editable=False, ), GridFieldText( "supplier__subcategory", title=format_lazy("{} - {}", _("supplier"), _("subcategory")), initially_hidden=True, editable=False, ), GridFieldText( "supplier__owner", title=format_lazy("{} - {}", _("supplier"), _("owner")), initially_hidden=True, field_name="supplier__owner__name", formatter="detail", extra='"role":"input/supplier"', editable=False, ), GridFieldText( "supplier__source", title=format_lazy("{} - {}", _("supplier"), _("source")), initially_hidden=True, editable=False, ), GridFieldLastModified( "supplier__lastmodified", title=format_lazy("{} - {}", _("supplier"), _("last modified")), initially_hidden=True, editable=False, ), GridFieldText( "end_items", title=_("end items"), editable=False, search=False, sortable=False, initially_hidden=True, formatter="listdetail", extra='"role":"input/item"', ), ) if settings.ERP_CONNECTOR: actions = [ { "name": "erp_incr_export", "label": format_lazy("export to {erp}", erp=settings.ERP_CONNECTOR), "function": "ERPconnection.IncrementalExport(jQuery('#grid'),'PO')", } ] else: actions = [ { "name": "proposed", "label": format_lazy( _("change status to {status}"), status=_("proposed") ), "function": "grid.setStatus('proposed')", }, { "name": "approved", "label": format_lazy( _("change status to {status}"), status=_("approved") ), "function": "grid.setStatus('approved')", }, { "name": "confirmed", "label": format_lazy( _("change status to {status}"), status=_("confirmed") ), "function": "grid.setStatus('confirmed')", }, { "name": "completed", "label": format_lazy( _("change status to {status}"), status=_("completed") ), "function": "grid.setStatus('completed')", }, { "name": "closed", "label": format_lazy( _("change status to {status}"), status=_("closed") ), "function": "grid.setStatus('closed')", }, ] @classmethod def initialize(reportclass, request): if reportclass._attributes_added != 2: reportclass._attributes_added = 2 for f in getAttributeFields(PurchaseOrder): reportclass.rows += (f,) for f in getAttributeFields(Item, related_name_prefix="item"): f.editable = False reportclass.rows += (f,) for f in getAttributeFields(Location, related_name_prefix="location"): f.editable = False reportclass.rows += (f,) for f in getAttributeFields(Supplier, related_name_prefix="supplier"): f.editable = False reportclass.rows += (f,)
class OverviewReport(GridPivot): """ A report showing the loading of each resource. """ template = "output/resource.html" title = _("Resource report") model = Resource permissions = (("view_resource_report", "Can view resource report"), ) editable = False help_url = "user-guide/user-interface/plan-analysis/resource-report.html" rows = ( GridFieldText( "resource", title=_("resource"), key=True, editable=False, field_name="name", formatter="detail", extra='"role":"input/resource"', ), GridFieldText( "description", title=_("description"), editable=False, field_name="description", initially_hidden=True, ), GridFieldText( "category", title=_("category"), editable=False, field_name="category", initially_hidden=True, ), GridFieldText( "subcategory", title=_("subcategory"), editable=False, field_name="subcategory", initially_hidden=True, ), GridFieldText( "type", title=_("type"), editable=False, field_name="type", initially_hidden=True, ), GridFieldBool( "constrained", title=_("constrained"), editable=False, field_name="constrained", initially_hidden=True, ), GridFieldNumber( "maximum", title=_("maximum"), editable=False, field_name="maximum", initially_hidden=True, ), GridFieldText( "maximum_calendar", title=_("maximum calendar"), editable=False, field_name="maximum_calendar__name", formatter="detail", extra='"role":"input/calendar"', initially_hidden=True, ), GridFieldCurrency( "cost", title=_("cost"), editable=False, field_name="cost", initially_hidden=True, ), GridFieldDuration( "maxearly", title=_("maxearly"), editable=False, field_name="maxearly", initially_hidden=True, ), GridFieldText( "setupmatrix", title=_("setupmatrix"), editable=False, field_name="setupmatrix__name", formatter="detail", extra='"role":"input/setupmatrix"', initially_hidden=True, ), GridFieldText( "setup", title=_("setup"), editable=False, field_name="setup", initially_hidden=True, ), GridFieldText( "location__name", title=_("location"), editable=False, field_name="location__name", formatter="detail", extra='"role":"input/location"', ), GridFieldText( "location__description", title=format_lazy("{} - {}", _("location"), _("description")), editable=False, initially_hidden=True, ), GridFieldText( "location__category", title=format_lazy("{} - {}", _("location"), _("category")), editable=False, initially_hidden=True, ), GridFieldText( "location__subcategory", title=format_lazy("{} - {}", _("location"), _("subcategory")), editable=False, initially_hidden=True, ), GridFieldText( "location__available", title=format_lazy("{} - {}", _("location"), _("available")), editable=False, field_name="location__available__name", formatter="detail", extra='"role":"input/calendar"', initially_hidden=True, ), GridFieldText( "avgutil", title=_("utilization %"), formatter="percentage", editable=False, width=100, align="center", ), GridFieldText( "available_calendar", title=_("available calendar"), editable=False, field_name="available__name", formatter="detail", extra='"role":"input/calendar"', initially_hidden=True, ), GridFieldText( "owner", title=_("owner"), editable=False, field_name="owner__name", formatter="detail", extra='"role":"input/resource"', initially_hidden=True, ), ) crosses = ( ("available", { "title": _("available") }), ("unavailable", { "title": _("unavailable") }), ("setuptime", { "title": _("setup") }), ("load", { "title": _("load") }), ("utilization", { "title": _("utilization %") }), ) @classmethod def initialize(reportclass, request): if reportclass._attributes_added != 2: reportclass._attributes_added = 2 reportclass.attr_sql = "" # Adding custom resource attributes for f in getAttributeFields(Resource, initially_hidden=True): f.editable = False reportclass.rows += (f, ) reportclass.attr_sql += "res.%s, " % f.name.split("__")[-1] # Adding custom location attributes for f in getAttributeFields(Location, related_name_prefix="location", initially_hidden=True): f.editable = False reportclass.rows += (f, ) reportclass.attr_sql += "location.%s, " % f.name.split( "__")[-1] @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: request.session["lasttab"] = "plan" return { "units": reportclass.getUnits(request), "title": force_text(Resource._meta.verbose_name) + " " + args[0], "post_title": _("plan"), } else: return {"units": reportclass.getUnits(request)} @classmethod def basequeryset(reportclass, request, *args, **kwargs): if args and args[0]: queryset = Resource.objects.filter(name=args[0]) else: queryset = Resource.objects.all() return queryset.annotate(avgutil=RawSQL( """ select ( coalesce(sum(out_resourceplan.load),0) + coalesce(sum(out_resourceplan.setup),0) ) * 100.0 / coalesce(greatest(sum(out_resourceplan.available), 0.0001),1) as avg_util from out_resourceplan where out_resourceplan.startdate >= %s and out_resourceplan.startdate < %s and out_resourceplan.resource = resource.name """, (request.report_startdate, request.report_enddate), )) @classmethod def getUnits(reportclass, request): try: units = Parameter.objects.using( request.database).get(name="loading_time_units") if units.value == "hours": return (1.0, _("hours")) elif units.value == "weeks": return (168, _("weeks")) else: return (24, _("days")) except Exception: return (24, _("days")) @classmethod def query(reportclass, request, basequery, sortsql="1 asc"): basesql, baseparams = basequery.query.get_compiler( basequery.db).as_sql(with_col_aliases=False) # Get the time units units = OverviewReport.getUnits(request) # Assure the item hierarchy is up to date Resource.rebuildHierarchy(database=basequery.db) # Execute the query query = """ select res.name, res.description, res.category, res.subcategory, res.type, res.constrained, res.maximum, res.maximum_calendar_id, res.cost, res.maxearly, res.setupmatrix_id, res.setup, location.name, location.description, location.category, location.subcategory, location.available_id, res.avgutil, res.available_id available_calendar, res.owner_id, %s d.bucket as col1, d.startdate as col2, coalesce(sum(out_resourceplan.available),0) / (case when res.type = 'buckets' then 1 else %f end) as available, coalesce(sum(out_resourceplan.unavailable),0) / (case when res.type = 'buckets' then 1 else %f end) as unavailable, coalesce(sum(out_resourceplan.load),0) / (case when res.type = 'buckets' then 1 else %f end) as loading, coalesce(sum(out_resourceplan.setup),0) / (case when res.type = 'buckets' then 1 else %f end) as setup from (%s) res left outer join location on res.location_id = location.name -- 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 -- Utilization info left join out_resourceplan on res.name = out_resourceplan.resource and d.startdate <= out_resourceplan.startdate and d.enddate > out_resourceplan.startdate and out_resourceplan.startdate >= '%s' and out_resourceplan.startdate < '%s' -- Grouping and sorting group by res.name, res.description, res.category, res.subcategory, res.type, res.maximum, res.maximum_calendar_id, res.available_id, res.cost, res.maxearly, res.setupmatrix_id, res.setup, location.name, location.description, location.category, location.subcategory, location.available_id, res.avgutil, res.owner_id, res.constrained, %s d.bucket, d.startdate order by %s, d.startdate """ % ( reportclass.attr_sql, units[0], units[0], units[0], units[0], basesql, request.report_bucket, request.report_startdate, request.report_enddate, request.report_startdate, request.report_enddate, reportclass.attr_sql, sortsql, ) # Build the python result with connections[request.database].chunked_cursor() as cursor_chunked: cursor_chunked.execute(query, baseparams) for row in cursor_chunked: numfields = len(row) if row[numfields - 4] != 0: util = round(row[numfields - 2] * 100 / row[numfields - 4], 2) else: util = 0 result = { "resource": row[0], "description": row[1], "category": row[2], "subcategory": row[3], "type": row[4], "constrained": row[5], "maximum": row[6], "maximum_calendar": row[7], "cost": row[8], "maxearly": row[9], "setupmatrix": row[10], "setup": row[11], "location__name": row[12], "location__description": row[13], "location__category": row[14], "location__subcategory": row[15], "location__available": row[16], "avgutil": round(row[17], 2), "available_calendar": row[18], "owner": row[19], "bucket": row[numfields - 6], "startdate": row[numfields - 5], "available": row[numfields - 4], "unavailable": row[numfields - 3], "load": row[numfields - 2], "setuptime": row[numfields - 1], "utilization": util, } idx = 20 for f in getAttributeFields(Resource): result[f.field_name] = row[idx] idx += 1 for f in getAttributeFields(Location): result[f.field_name] = row[idx] idx += 1 yield result
class DetailReport(OperationPlanMixin, 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 base = reportclass.operationplanExtraBasequery(base, request) return base.select_related().extra(select={ 'feasible': "coalesce((operationplan.plan->>'feasible')::boolean, true)", }) @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('demand', title=_('demands'), formatter='demanddetail', extra='"role":"input/demand"', width=300, editable=False, sortable=False), GridFieldBool('feasible', title=_('feasible'), editable=False, initially_hidden=True, search=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), GridFieldNumber('item__cost', title=string_concat(_('item'), ' - ', _('cost')), 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), GridFieldBool('feasible', title=_('feasible'), editable=False, initially_hidden=True, search=False), )
class InventoryDetail(OperationPlanMixin, GridReport): """ A list report to show OperationPlanMaterial. """ template = "input/operationplanreport.html" title = _("Inventory detail") model = OperationPlanMaterial permissions = (("view_inventory_report", "Can view inventory report"),) frozenColumns = 0 editable = True multiselect = True height = 250 help_url = "user-interface/plan-analysis/inventory-detail-report.html" @classmethod def basequeryset(reportclass, request, *args, **kwargs): if len(args) and args[0]: if request.path_info.startswith( "/data/input/operationplanmaterial/item/" ) or request.path_info.startswith("/detail/input/item/"): base = OperationPlanMaterial.objects.filter(item=args[0]) elif request.path_info.startswith( "/data/input/operationplanmaterial/buffer/" ): i_b_l = args[0].split(" @ ") if len(i_b_l) == 1: buffer = Buffer.objects.get(id=args[0]) base = OperationPlanMaterial.objects.filter( item=buffer.item.name, location=buffer.location.name ) elif len(i_b_l) == 2: base = OperationPlanMaterial.objects.filter( item=i_b_l[0], location=i_b_l[1] ) else: base = OperationPlanMaterial.objects.filter( item=i_b_l[0], location=i_b_l[2], operationplan__batch=i_b_l[1] ) else: base = OperationPlanMaterial.objects base = reportclass.operationplanExtraBasequery(base, request) return base.select_related().annotate( feasible=RawSQL( "coalesce((operationplan.plan->>'feasible')::boolean, true)", [] ) ) @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: if request.path_info.startswith( "/data/input/operationplanmaterial/item/" ) or request.path_info.startswith("/detail/input/item/"): request.session["lasttab"] = "inventorydetail" return { "active_tab": "inventorydetail", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": _("inventory detail"), } elif request.path_info.startswith( "/data/input/operationplanmaterial/buffer/" ): request.session["lasttab"] = "plandetail" dlmtr = args[0].find(" @ ") if dlmtr != -1: item = args[0][:dlmtr] location = args[0][dlmtr + 3 :] else: buffer = Buffer.objects.get(id=args[0]) item = buffer.item.name location = buffer.location.name return { "active_tab": "plandetail", "model": Buffer, "title": force_text(Buffer._meta.verbose_name) + " " + item + " @ " + location, "post_title": _("plan detail"), } else: return {"active_tab": "plandetail", "model": OperationPlanMaterial} rows = ( GridFieldInteger( "id", title=_("identifier"), key=True, editable=False, formatter="detail", extra='"role":"input/operationplanmaterial"', initially_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"', ), GridFieldText("operationplan__reference", title=_("reference"), editable=False), GridFieldText( "owner", title=_("owner"), field_name="operationplan__owner__reference", formatter="detail", extra="role:'input/manufacturingorder'", initially_hidden=True, ), GridFieldText( "operationplan__batch", title=_("batch"), editable=False, initially_hidden=True, ), GridFieldText( "color", title=_("inventory status"), formatter="color", field_name="operationplan__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=format_lazy("{} - {}", _("operation"), _("description")), editable=False, initially_hidden=True, ), GridFieldText( "operationplan__operation__category", title=format_lazy("{} - {}", _("operation"), _("category")), editable=False, initially_hidden=True, ), GridFieldText( "operationplan__operation__subcategory", title=format_lazy("{} - {}", _("operation"), _("subcategory")), editable=False, initially_hidden=True, ), GridFieldText( "operationplan__operation__type", title=format_lazy("{} - {}", _("operation"), _("type")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__duration", title=format_lazy("{} - {}", _("operation"), _("duration")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__duration_per", title=format_lazy("{} - {}", _("operation"), _("duration per unit")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__fence", title=format_lazy("{} - {}", _("operation"), _("release fence")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__posttime", title=format_lazy("{} - {}", _("operation"), _("post-op time")), initially_hidden=True, ), GridFieldNumber( "operationplan__operation__sizeminimum", title=format_lazy("{} - {}", _("operation"), _("size minimum")), initially_hidden=True, ), GridFieldNumber( "operationplan__operation__sizemultiple", title=format_lazy("{} - {}", _("operation"), _("size multiple")), initially_hidden=True, ), GridFieldNumber( "operationplan__operation__sizemaximum", title=format_lazy("{} - {}", _("operation"), _("size maximum")), initially_hidden=True, ), GridFieldInteger( "operationplan__operation__priority", title=format_lazy("{} - {}", _("operation"), _("priority")), initially_hidden=True, ), GridFieldDateTime( "operationplan__operation__effective_start", title=format_lazy("{} - {}", _("operation"), _("effective start")), initially_hidden=True, ), GridFieldDateTime( "operationplan__operation__effective_end", title=format_lazy("{} - {}", _("operation"), _("effective end")), initially_hidden=True, ), GridFieldCurrency( "operationplan__operation__cost", title=format_lazy("{} - {}", _("operation"), _("cost")), initially_hidden=True, ), GridFieldText( "operationplan__operation__search", title=format_lazy("{} - {}", _("operation"), _("search mode")), initially_hidden=True, ), GridFieldText( "operationplan__operation__source", title=format_lazy("{} - {}", _("operation"), _("source")), initially_hidden=True, ), GridFieldLastModified( "operationplan__operation__lastmodified", title=format_lazy("{} - {}", _("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"', ), GridFieldDuration( "periodofcover", title=_("period of cover"), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), 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"', ), 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( "delay", title=_("delay"), field_name="operationplan__delay", editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldNumber( "operationplan__quantity", title=_("operationplan quantity"), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldText( "demands", title=_("demands"), formatter="demanddetail", extra='"role":"input/demand"', width=300, editable=False, sortable=False, ), GridFieldBool( "feasible", title=_("feasible"), editable=False, initially_hidden=True, search=False, ), # 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, ), 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, ), GridFieldChoice( "status", title=_("material status"), choices=OperationPlanMaterial.OPMstatus, ), GridFieldLastModified("lastmodified", initially_hidden=True), )
class DistributionOrderList(OperationPlanMixin, GridReport): template = "input/operationplanreport.html" title = _("distribution orders") default_sort = (1, "desc") model = DistributionOrder frozenColumns = 1 multiselect = True editable = True height = 250 help_url = "modeling-wizard/distribution/distribution-orders.html" @classmethod def extra_context(reportclass, request, *args, **kwargs): if args and args[0]: paths = request.path.split("/") if paths[4] == "operationplanmaterial": return { "active_tab": "distributionorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": force_text( _("in transit in %(loc)s at %(date)s") % {"loc": args[1], "date": args[2]} ), } elif paths[4] == "produced": return { "active_tab": "distributionorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": force_text( _("received in %(loc)s between %(date1)s and %(date2)s") % {"loc": args[1], "date1": args[2], "date2": args[3]} ), } elif paths[4] == "consumed": return { "active_tab": "distributionorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": force_text( _("shipped from %(loc)s between %(date1)s and %(date2)s") % {"loc": args[1], "date1": args[2], "date2": args[3]} ), } elif paths[4] == "item": return { "active_tab": "distributionorders", "model": Item, "title": force_text(Item._meta.verbose_name) + " " + args[0], "post_title": _("distribution orders"), } elif paths[4] == "location": path = paths[-2] if path == "in": return { "active_tab": "inboundorders", "model": Location, "title": force_text(Location._meta.verbose_name) + " " + args[0], "post_title": _("inbound distribution"), } elif path == "out": return { "active_tab": "outboundorders", "model": Location, "title": force_text(Location._meta.verbose_name) + " " + args[0], "post_title": _("outbound distribution"), } else: return {"active_tab": "edit", "model": Item} else: return {"active_tab": "edit"} @classmethod def basequeryset(reportclass, request, *args, **kwargs): q = DistributionOrder.objects.all() if args and args[0]: paths = request.path.split("/") if paths[4] == "operationplanmaterial": q = q.filter(Q(origin=args[1]) | Q(destination=args[1])).filter( item__name=args[0], startdate__lt=args[2], enddate__gte=args[2] ) elif paths[4] == "item": q = q.filter(item__name=args[0]) elif paths[4] == "produced": q = q.filter( destination__name=args[1], item__name=args[0], enddate__gte=args[2], enddate__lt=args[3], ) elif paths[4] == "consumed": q = q.filter( origin__name=args[1], item__name=args[0], startdate__gte=args[2], startdate__lt=args[3], ) elif paths[4] == "location": path = paths[-2] if path == "out": q = q.filter(origin_id=args[0]) elif path == "in": q = q.filter(destination_id=args[0]) q = reportclass.operationplanExtraBasequery(q, request) return q.annotate( total_cost=Cast(F("item__cost") * F("quantity"), output_field=FloatField()), total_volume=Cast( F("item__volume") * F("quantity"), output_field=FloatField() ), total_weight=Cast( F("item__weight") * F("quantity"), output_field=FloatField() ), feasible=RawSQL( "coalesce((operationplan.plan->>'feasible')::boolean, true)", [] ), computed_color=RawSQL( """ case when operationplan.color >= 999999 and operationplan.plan ? 'item' then 999999 - extract(epoch from operationplan.delay)/86400.0 + 1000000 when operationplan.color >= 999999 and not(operationplan.plan ? 'item') then 999999 - extract(epoch from operationplan.delay)/86400.0 else operationplan.color end """, [], ), ) rows = ( GridFieldText( "reference", title=_("reference"), key=True, formatter="detail", extra='role:"input/distributionorder"', editable=not settings.ERP_CONNECTOR, ), GridFieldNumber( "computed_color", title=_("inventory status"), formatter="color", width="125", editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldNumber("color", hidden=True), GridFieldHierarchicalText( "item", title=_("item"), field_name="item__name", formatter="detail", extra='"role":"input/item"', model=Item, ), GridFieldText( "origin", title=_("origin"), field_name="origin__name", formatter="detail", extra='"role":"input/location"', ), GridFieldText( "destination", title=_("destination"), field_name="destination__name", formatter="detail", extra='"role":"input/location"', ), GridFieldDateTime( "startdate", title=_("shipping date"), extra='"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"min"', ), GridFieldDateTime( "enddate", title=_("receipt date"), extra='"formatoptions":{"srcformat":"Y-m-d H:i:s","newformat":"Y-m-d H:i:s", "defaultValue":""}, "summaryType":"max"', ), GridFieldNumber( "quantity", title=_("quantity"), extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldChoice( "status", title=_("status"), choices=DistributionOrder.orderstatus, editable=not settings.ERP_CONNECTOR, ), GridFieldCurrency( "item__cost", title=format_lazy("{} - {}", _("item"), _("cost")), editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldNumber( "item__volume", title=format_lazy("{} - {}", _("item"), _("volume")), initially_hidden=True, editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldNumber( "item__weight", title=format_lazy("{} - {}", _("item"), _("weight")), initially_hidden=True, editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldCurrency( "total_cost", title=_("total cost"), editable=False, search=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldNumber( "total_volume", title=_("total volume"), editable=False, search=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldNumber( "total_weight", title=_("total weight"), editable=False, search=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"sum"', ), GridFieldText( "batch", title=_("batch"), editable="true", initially_hidden=True ), GridFieldNumber( "criticality", title=_("criticality"), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldDuration( "delay", title=_("delay"), editable=False, initially_hidden=True, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldJSON( "demands", title=_("demands"), editable=False, search=True, sortable=False, formatter="demanddetail", extra='"role":"input/demand"', ), GridFieldText("source", title=_("source"), initially_hidden=True), GridFieldLastModified("lastmodified"), GridFieldBool( "feasible", title=_("feasible"), editable=False, initially_hidden=True, search=False, ), # 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, ), 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 origin location GridFieldText( "origin__description", title=format_lazy("{} - {}", _("origin"), _("description")), initially_hidden=True, editable=False, ), GridFieldText( "origin__category", title=format_lazy("{} - {}", _("origin"), _("category")), initially_hidden=True, editable=False, ), GridFieldText( "origin__subcategory", title=format_lazy("{} - {}", _("origin"), _("subcategory")), initially_hidden=True, editable=False, ), GridFieldText( "origin__available", title=format_lazy("{} - {}", _("origin"), _("available")), initially_hidden=True, field_name="origin__available__name", formatter="detail", extra='"role":"input/calendar"', editable=False, ), GridFieldText( "origin__owner", title=format_lazy("{} - {}", _("origin"), _("owner")), initially_hidden=True, field_name="origin__owner__name", formatter="detail", extra='"role":"input/location"', editable=False, ), GridFieldText( "origin__source", title=format_lazy("{} - {}", _("origin"), _("source")), initially_hidden=True, editable=False, ), GridFieldLastModified( "origin__lastmodified", title=format_lazy("{} - {}", _("origin"), _("last modified")), initially_hidden=True, editable=False, ), # Optional fields referencing the destination location GridFieldText( "destination__description", title=format_lazy("{} - {}", _("destination"), _("description")), initially_hidden=True, editable=False, ), GridFieldText( "destination__category", title=format_lazy("{} - {}", _("destination"), _("category")), initially_hidden=True, editable=False, ), GridFieldText( "destination__subcategory", title=format_lazy("{} - {}", _("destination"), _("subcategory")), initially_hidden=True, editable=False, ), GridFieldText( "destination__available", title=format_lazy("{} - {}", _("destination"), _("available")), initially_hidden=True, field_name="origin__available__name", formatter="detail", extra='"role":"input/calendar"', editable=False, ), GridFieldText( "destination__owner", title=format_lazy("{} - {}", _("destination"), _("owner")), initially_hidden=True, field_name="origin__owner__name", formatter="detail", extra='"role":"input/location"', editable=False, ), GridFieldText( "destination__source", title=format_lazy("{} - {}", _("destination"), _("source")), initially_hidden=True, editable=False, ), GridFieldLastModified( "destination__lastmodified", title=format_lazy("{} - {}", _("destination"), _("last modified")), initially_hidden=True, editable=False, ), GridFieldText( "end_items", title=_("end items"), editable=False, search=False, sortable=False, initially_hidden=True, formatter="listdetail", extra='"role":"input/item"', ), ) if settings.ERP_CONNECTOR: actions = [ { "name": "erp_incr_export", "label": format_lazy("export to {erp}", erp=settings.ERP_CONNECTOR), "function": "ERPconnection.IncrementalExport(jQuery('#grid'),'DO')", } ] else: actions = [ { "name": "proposed", "label": format_lazy( _("change status to {status}"), status=_("proposed") ), "function": "grid.setStatus('proposed')", }, { "name": "approved", "label": format_lazy( _("change status to {status}"), status=_("approved") ), "function": "grid.setStatus('approved')", }, { "name": "confirmed", "label": format_lazy( _("change status to {status}"), status=_("confirmed") ), "function": "grid.setStatus('confirmed')", }, { "name": "completed", "label": format_lazy( _("change status to {status}"), status=_("completed") ), "function": "grid.setStatus('completed')", }, { "name": "closed", "label": format_lazy( _("change status to {status}"), status=_("closed") ), "function": "grid.setStatus('closed')", }, ] @classmethod def initialize(reportclass, request): if reportclass._attributes_added != 2: reportclass._attributes_added = 2 for f in getAttributeFields(DistributionOrder): reportclass.rows += (f,) for f in getAttributeFields(Item, related_name_prefix="item"): f.editable = False reportclass.rows += (f,) for f in getAttributeFields(Location, related_name_prefix="origin"): f.editable = False reportclass.rows += (f,) for f in getAttributeFields(Location, related_name_prefix="destination"): f.editable = False reportclass.rows += (f,)
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 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 ResourceList(GridReport): title = _("resources") basequeryset = Resource.objects.all() model = Resource frozenColumns = 1 help_url = "modeling-wizard/manufacturing-capacity/resources.html" rows = ( GridFieldText( "name", title=_("name"), key=True, formatter="detail", extra='"role":"input/resource"', ), GridFieldText("description", title=_("description")), GridFieldText("category", title=_("category"), initially_hidden=True), GridFieldText("subcategory", title=_("subcategory"), initially_hidden=True), GridFieldHierarchicalText( "location", title=_("location"), field_name="location__name", formatter="detail", extra='"role":"input/location"', model=Location, ), GridFieldText( "owner", title=_("owner"), field_name="owner__name", formatter="detail", extra='"role":"input/resource"', initially_hidden=True, ), GridFieldChoice("type", title=_("type"), choices=Resource.types), GridFieldBool("constrained", title=_("constrained")), GridFieldNumber("maximum", title=_("maximum")), GridFieldText( "maximum_calendar", title=_("maximum calendar"), field_name="maximum_calendar__name", formatter="detail", extra='"role":"input/calendar"', ), GridFieldText( "available", title=_("available"), field_name="available__name", formatter="detail", extra='"role":"input/calendar"', ), GridFieldCurrency("cost", title=_("cost"), initially_hidden=True), GridFieldDuration("maxearly", title=_("maxearly"), initially_hidden=True), GridFieldText( "setupmatrix", title=_("setup matrix"), field_name="setupmatrix__name", formatter="detail", extra='"role":"input/setupmatrix"', initially_hidden=True, ), GridFieldText("setup", title=_("setup"), initially_hidden=True), GridFieldText("source", title=_("source"), initially_hidden=True), # Translator: xgettext:no-python-format GridFieldNumber("efficiency", title=_("efficiency %"), formatter="percentage"), GridFieldText( "efficiency_calendar", # Translator: xgettext:no-python-format title=_("efficiency % calendar"), initially_hidden=True, field_name="efficiency_calendar__name", formatter="detail", extra='"role":"input/calendar"', ), GridFieldLastModified("lastmodified"), # 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, ), )
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 ResourceList(GridReport): title = _("resources") basequeryset = Resource.objects.all() model = Resource frozenColumns = 1 help_url = "modeling-wizard/manufacturing-capacity/resources.html" message_when_empty = Template(""" <h3>Define resources</h3> <br> Resources represent capacity.<br> They represent a machine, a group of machines, an operator, a group of operators, or some logical capacity constraint.<br> <br><br> <div role="group" class="btn-group.btn-group-justified"> <a href="{{request.prefix}}/data/input/resource/add/" class="btn btn-primary">Create a single resource<br>in a form</a> <a href="{{request.prefix}}/wizard/load/production/?currentstep=8" class="btn btn-primary">Wizard to upload resources<br>from a spreadsheet</a> </div> <br> """) rows = ( GridFieldText( "name", title=_("name"), key=True, formatter="detail", extra='"role":"input/resource"', ), GridFieldText("description", title=_("description")), GridFieldText("category", title=_("category"), initially_hidden=True), GridFieldText("subcategory", title=_("subcategory"), initially_hidden=True), GridFieldHierarchicalText( "location", title=_("location"), field_name="location__name", formatter="detail", extra='"role":"input/location"', model=Location, ), GridFieldText( "owner", title=_("owner"), field_name="owner__name", formatter="detail", extra='"role":"input/resource"', initially_hidden=True, ), GridFieldChoice("type", title=_("type"), choices=Resource.types), GridFieldBool("constrained", title=_("constrained")), GridFieldNumber("maximum", title=_("maximum")), GridFieldText( "maximum_calendar", title=_("maximum calendar"), field_name="maximum_calendar__name", formatter="detail", extra='"role":"input/calendar"', ), GridFieldText( "available", title=_("available"), field_name="available__name", formatter="detail", extra='"role":"input/calendar"', ), GridFieldCurrency("cost", title=_("cost"), initially_hidden=True), GridFieldDuration("maxearly", title=_("maxearly"), initially_hidden=True), GridFieldText( "setupmatrix", title=_("setup matrix"), field_name="setupmatrix__name", formatter="detail", extra='"role":"input/setupmatrix"', initially_hidden=True, ), GridFieldText("setup", title=_("setup"), initially_hidden=True), GridFieldText("source", title=_("source"), initially_hidden=True), # Translator: xgettext:no-python-format GridFieldNumber("efficiency", title=_("efficiency %"), formatter="percentage"), GridFieldText( "efficiency_calendar", # Translator: xgettext:no-python-format title=_("efficiency % calendar"), initially_hidden=True, field_name="efficiency_calendar__name", formatter="detail", extra='"role":"input/calendar"', ), GridFieldLastModified("lastmodified"), # 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, ), )
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 ResourceDetail(OperationPlanMixin, GridReport): template = "input/operationplanreport.html" title = _("resource detail") model = OperationPlanResource permissions = (("view_resource_report", "Can view resource report"), ) frozenColumns = 3 editable = True multiselect = True height = 250 help_url = "user-interface/plan-analysis/resource-detail-report.html" message_when_empty = Template(""" <h3>Resource detail</h3> <br> This table has a list of all manufacturing orders assigned to a certain certain resource.<br><br> The planning algorithm will populate this table, and as a user you normally don't need to create records in this table.<br> <br> """) @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) if "calendarstart" in request.GET: base = base.filter( Q(operationplan__enddate__gte=request.GET["calendarstart"]) | (Q(operationplan__enddate__isnull=True) & Q(operationplan__startdate__gte=request. GET["calendarstart"]))) if "calendarend" in request.GET: base = base.filter( Q(operationplan__startdate__lte=request.GET["calendarend"]) | (Q(operationplan__startdate__isnull=True) & Q(operationplan__enddate__lte=request.GET["calendarend"]))) return base.select_related().annotate( opplan_duration=RawSQL( "(operationplan.enddate - operationplan.startdate)", []), opplan_net_duration=RawSQL( "(operationplan.enddate - operationplan.startdate - coalesce((operationplan.plan->>'unavailable')::int * interval '1 second', interval '0 second'))", [], ), setup_end=RawSQL("(operationplan.plan->>'setupend')", []), setup_duration=RawSQL("(operationplan.plan->>'setup')", []), feasible=RawSQL( "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 { "default_operationplan_type": "MO", "groupBy": "operationplan__status", "active_tab": "plandetail", "model": Resource, "title": force_text(Resource._meta.verbose_name) + " " + args[0], "post_title": _("plan detail"), } else: return { "default_operationplan_type": "MO", "groupBy": "operationplan__status", "active_tab": "plandetail", "model": OperationPlanResource, } rows = ( GridFieldInteger( "id", title="identifier", key=True, editable=False, formatter="detail", extra='"role":"input/operationplanresource"', initially_hidden=True, ), GridFieldText( "resource", title=_("resource"), field_name="resource__name", formatter="detail", extra='"role":"input/resource"', ), GridFieldText("operationplan__reference", title=_("reference"), editable=False), GridFieldText( "owner", title=_("owner"), field_name="operationplan__owner__reference", formatter="detail", extra="role:'input/manufacturingorder'", initially_hidden=True, ), GridFieldText( "color", title=_("inventory status"), formatter="color", field_name="operationplan__color", width="125", editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"min"', ), GridFieldText( "operationplan__item", title=_("item"), editable=False, formatter="detail", extra='"role":"input/item"', ), GridFieldText( "operationplan__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__batch", title=_("batch"), editable=False, field_name="operationplan__batch", initially_hidden=True, ), GridFieldText( "operationplan__operation__description", title=format_lazy("{} - {}", _("operation"), _("description")), editable=False, initially_hidden=True, ), GridFieldText( "operationplan__operation__category", title=format_lazy("{} - {}", _("operation"), _("category")), editable=False, initially_hidden=True, ), GridFieldText( "operationplan__operation__subcategory", title=format_lazy("{} - {}", _("operation"), _("subcategory")), editable=False, initially_hidden=True, ), GridFieldText( "operationplan__operation__type", title=format_lazy("{} - {}", _("operation"), _("type")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__duration", title=format_lazy("{} - {}", _("operation"), _("duration")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__duration_per", title=format_lazy("{} - {}", _("operation"), _("duration per unit")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__fence", title=format_lazy("{} - {}", _("operation"), _("release fence")), initially_hidden=True, ), GridFieldDuration( "operationplan__operation__posttime", title=format_lazy("{} - {}", _("operation"), _("post-op time")), initially_hidden=True, ), GridFieldNumber( "operationplan__operation__sizeminimum", title=format_lazy("{} - {}", _("operation"), _("size minimum")), initially_hidden=True, ), GridFieldNumber( "operationplan__operation__sizemultiple", title=format_lazy("{} - {}", _("operation"), _("size multiple")), initially_hidden=True, ), GridFieldNumber( "operationplan__operation__sizemaximum", title=format_lazy("{} - {}", _("operation"), _("size maximum")), initially_hidden=True, ), GridFieldInteger( "operationplan__operation__priority", title=format_lazy("{} - {}", _("operation"), _("priority")), initially_hidden=True, ), GridFieldDateTime( "operationplan__operation__effective_start", title=format_lazy("{} - {}", _("operation"), _("effective start")), initially_hidden=True, ), GridFieldDateTime( "operationplan__operation__effective_end", title=format_lazy("{} - {}", _("operation"), _("effective end")), initially_hidden=True, ), GridFieldCurrency( "operationplan__operation__cost", title=format_lazy("{} - {}", _("operation"), _("cost")), initially_hidden=True, ), GridFieldText( "operationplan__operation__search", title=format_lazy("{} - {}", _("operation"), _("search mode")), initially_hidden=True, ), GridFieldText( "operationplan__operation__source", title=format_lazy("{} - {}", _("operation"), _("source")), initially_hidden=True, ), GridFieldLastModified( "operationplan__operation__lastmodified", title=format_lazy("{} - {}", _("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( "delay", title=_("delay"), field_name="operationplan__delay", editable=False, extra='"formatoptions":{"defaultValue":""}, "summaryType":"max"', ), GridFieldText( "demands", 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"), 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, search=False, ), GridFieldBool( "feasible", title=_("feasible"), editable=False, initially_hidden=True, search=False, ), # Optional fields referencing the item GridFieldText( "operationplan__item__type", title=format_lazy("{} - {}", _("item"), _("type")), initially_hidden=True, editable=False, ), GridFieldText( "operationplan__item__description", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("item"), _("description")), ), GridFieldText( "operationplan__item__category", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("item"), _("category")), ), GridFieldText( "operationplan__item__subcategory", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("item"), _("subcategory")), ), GridFieldCurrency( "operationplan__item__cost", title=format_lazy("{} - {}", _("item"), _("cost")), initially_hidden=True, editable=False, ), GridFieldNumber( "operationplan__item__volume", title=format_lazy("{} - {}", _("item"), _("volume")), initially_hidden=True, editable=False, ), GridFieldNumber( "operationplan__item__weight", title=format_lazy("{} - {}", _("item"), _("weight")), initially_hidden=True, editable=False, ), GridFieldText( "operationplan__item__owner", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("item"), _("owner")), field_name="operationplan__item__owner__name", ), GridFieldText( "operationplan__item__source", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("item"), _("source")), ), GridFieldLastModified( "operationplan__item__lastmodified", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("item"), _("last modified")), ), # Optional fields referencing the operation location GridFieldText( "operationplan__operation__location__description", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("location"), _("description")), ), GridFieldText( "operationplan__operation__location__category", title=format_lazy("{} - {}", _("location"), _("category")), initially_hidden=True, editable=False, ), GridFieldText( "operationplan__operation__location__subcategory", title=format_lazy("{} - {}", _("location"), _("subcategory")), initially_hidden=True, editable=False, ), GridFieldText( "operationplan__operation__location__available", editable=False, title=format_lazy("{} - {}", _("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=format_lazy("{} - {}", _("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=format_lazy("{} - {}", _("location"), _("source")), ), GridFieldLastModified( "operationplan__operation__location__lastmodified", initially_hidden=True, editable=False, title=format_lazy("{} - {}", _("location"), _("last modified")), ), # Optional fields referencing the resource GridFieldText( "resource__description", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("description")), ), GridFieldText( "resource__category", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("category")), ), GridFieldText( "resource__subcategory", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("subcategory")), ), GridFieldText( "resource__type", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("type")), ), GridFieldBool( "resource__constrained", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("constrained")), ), GridFieldNumber( "resource__maximum", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("maximum")), ), GridFieldText( "resource__maximum_calendar", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("maximum calendar")), field_name="resource__maximum_calendar__name", formatter="detail", extra='"role":"input/calendar"', ), GridFieldCurrency( "resource__cost", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("cost")), ), GridFieldDuration( "resource__maxearly", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("maxearly")), ), GridFieldText( "resource__setupmatrix", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("setupmatrix")), field_name="resource__setupmatrix__name", formatter="detail", extra='"role":"input/setupmatrix"', ), GridFieldText( "resource__setup", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("resource"), _("setup")), ), GridFieldText( "resource_location", editable=False, initially_hidden=True, title=format_lazy("{} - {}", _("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=format_lazy("{} - {} - {}", _("resource"), _("location"), _("description")), ), GridFieldText( "resource__location__category", initially_hidden=True, editable=False, title=format_lazy("{} - {} - {}", _("resource"), _("location"), _("category")), ), GridFieldText( "resource__location__subcategory", initially_hidden=True, editable=False, title=format_lazy("{} - {} - {}", _("resource"), _("location"), _("subcategory")), ), GridFieldText( "resource__location__available", initially_hidden=True, editable=False, title=format_lazy("{} - {} - {}", _("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=format_lazy("{} - {} - {}", _("resource"), _("location"), _("owner")), initially_hidden=True, field_name="resource__location__owner__name", formatter="detail", ), GridFieldText( "resource__location__source", initially_hidden=True, editable=False, title=format_lazy("{} - {} - {}", _("resource"), _("location"), _("source")), ), # Status field currently not used # GridFieldChoice('status', title=_('load status'), choices=OperationPlanResource.OPRstatus), GridFieldLastModified("lastmodified", initially_hidden=True), )