class Customer_admin(MultiDBModelAdmin): model = Customer raw_id_fields = ("owner",) save_on_top = True fieldsets = ( (None, {"fields": ("name", "description", "owner")}), ( _("advanced"), { "fields": ["category", "subcategory"] + [a[0] for a in getAttributes(Location) if a[3]], "classes": ("collapse",), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_customer_change", "permissions": "input.change_customer", }, { "name": "messages", "label": _("messages"), "view": "admin:input_customer_comment", }, ]
class Supplier_admin(MultiDBModelAdmin): model = Supplier raw_id_fields = ("available", "owner") save_on_top = True fieldsets = ( (None, {"fields": ("name", "description")}), ( _("advanced"), { "fields": ["category", "subcategory"] + [a[0] for a in getAttributes(Supplier) if a[3]], "classes": ("collapse",), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_supplier_change", "permissions": "input.change_supplier", }, { "name": "purchaseorders", "label": _("purchase orders"), "view": "input_purchaseorder_by_supplier", }, { "name": "messages", "label": _("messages"), "view": "admin:input_supplier_comment", }, ]
def loadItems(self): print('Importing items...') cnt = 0 starttime = time() attrs = [ f[0] for f in getAttributes(Item) ] if attrs: attrsql = ', %s' % ', '.join(attrs) else: attrsql = '' self.cursor.execute(''' SELECT name, description, operation_id, owner_id, price, category, subcategory, source %s FROM item %s ''' % (attrsql, self.filter_where)) for i in self.cursor.fetchall(): cnt += 1 try: x = frepple.item(name=i[0], description=i[1], category=i[5], subcategory=i[6], source=i[7]) if i[2]: x.operation = frepple.operation(name=i[2]) if i[3]: x.owner = frepple.item(name=i[3]) if i[4]: x.price = i[4] idx = 8 for a in attrs: setattr(x, a, i[idx]) idx += 1 except Exception as e: print("Error:", e) print('Loaded %d items in %.2f seconds' % (cnt, time() - starttime))
class Calendar_admin(MultiDBModelAdmin): model = Calendar save_on_top = True inlines = [CalendarBucket_inline] fieldsets = ( (None, {"fields": ("name", "defaultvalue")}), ( _("advanced"), { "fields": ["description", "category", "subcategory"] + [a[0] for a in getAttributes(Calendar) if a[3]], "classes": ("collapse",), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_calendar_change", "permissions": "input.change_calendar", }, { "name": "messages", "label": _("messages"), "view": "admin:input_calendar_comment", }, ]
class ResourceSkill_admin(MultiDBModelAdmin): model = ResourceSkill raw_id_fields = ("resource", "skill") save_on_top = True fieldsets = ( (None, {"fields": ("resource", "skill")}), ( _("advanced"), { "fields": ["priority", "effective_start", "effective_end"] + [a[0] for a in getAttributes(ResourceSkill) if a[3]], "classes": ("collapse",), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_resourceskill_change", "permissions": "input.change_resoureskill", }, { "name": "messages", "label": _("messages"), "view": "admin:input_resourceskill_comment", }, ]
def loadItems(self): print('Importing items...') cnt = 0 starttime = time() attrs = [ f[0] for f in getAttributes(Item) ] if attrs: attrsql = ', %s' % ', '.join(attrs) else: attrsql = '' self.cursor.execute(''' SELECT name, description, owner_id, price, category, subcategory, source %s FROM item %s ''' % (attrsql, self.filter_where)) for i in self.cursor.fetchall(): cnt += 1 try: x = frepple.item(name=i[0], description=i[1], category=i[4], subcategory=i[5], source=i[6]) if i[2]: x.owner = frepple.item(name=i[2]) if i[3]: x.price = i[3] idx = 7 for a in attrs: setattr(x, a, i[idx]) idx += 1 except Exception as e: print("Error:", e) print('Loaded %d items in %.2f seconds' % (cnt, time() - starttime))
class Demand_admin(MultiDBModelAdmin): model = Demand raw_id_fields = ("customer", "item", "operation", "owner") fieldsets = ( ( None, { "fields": ( "name", "item", "location", "customer", "due", "quantity", "priority", "status", ) }, ), ( _("advanced"), { "fields": [ "description", "category", "subcategory", "batch", "operation", "minshipment", "maxlateness", ] + [a[0] for a in getAttributes(Demand) if a[3]], "classes": ("collapse",), }, ), ) save_on_top = True tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_demand_change", "permissions": "input.change_demand", }, {"name": "supplypath", "label": _("supply path"), "view": "supplypath_demand"}, { "name": "constraint", "label": _("why short or late?"), "view": "output_constraint_demand", }, {"name": "plan", "label": _("plan"), "view": "output_demand_pegging"}, { "name": "messages", "label": _("messages"), "view": "admin:input_demand_comment", }, ]
class Item_admin(MultiDBModelAdmin): model = Item save_on_top = True raw_id_fields = ("owner", ) search_fields = ("name", "description") fieldsets = ( (None, { "fields": ("name", "description", "cost", "owner", "uom") }), ( _("advanced"), { "fields": ["category", "subcategory", "type", "volume", "weight"] + [a[0] for a in getAttributes(Item) if a[3]], "classes": ("collapse", ), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_item_change", "permissions": "input.change_item", }, { "name": "supplypath", "label": _("supply path"), "view": "supplypath_item" }, { "name": "whereused", "label": _("where used"), "view": "whereused_item" }, { "name": "plan", "label": _("plan"), "view": "output_demand_plandetail" }, { "name": "inventory", "label": _("inventory"), "view": "output_buffer_plandetail_by_item", }, { "name": "inventorydetail", "label": _("inventory detail"), "view": "input_operationplanmaterial_plandetail_by_item", }, { "name": "messages", "label": _("messages"), "view": "admin:input_item_comment", }, ]
class Location_admin(MultiDBModelAdmin): model = Location raw_id_fields = ("available", "owner") save_on_top = True fieldsets = ( (None, { "fields": ("name", "owner") }), ( _("Advanced"), { "fields": ["description", "category", "subcategory", "available"] + [a[0] for a in getAttributes(Location) if a[3]], "classes": ("collapse", ), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_location_change", "permissions": "input.change_location", }, { "name": "inboundorders", "label": _("inbound distribution"), "view": "input_distributionorder_in_by_location", }, { "name": "outboundorders", "label": _("outbound distribution"), "view": "input_distributionorder_out_by_location", }, { "name": "manufacturingorders", "label": _("manufacturing orders"), "view": "input_manufacturingorder_by_location", }, { "name": "purchaseorders", "label": _("purchase orders"), "view": "input_purchaseorder_by_location", }, { "name": "messages", "label": _("messages"), "view": "admin:input_location_comment", }, ]
class Buffer_admin(MultiDBModelAdmin): model = Buffer raw_id_fields = ("location", "item", "minimum_calendar") fieldsets = ( (None, {"fields": ("item", "location", "onhand", "minimum")}), ( _("advanced"), { "fields": [ "batch", "description", "category", "subcategory", "type", "minimum_calendar", "min_interval", ] + [a[0] for a in getAttributes(Buffer) if a[3]], "classes": ("collapse",), }, ), ) save_on_top = True tabs = [ { "name": "edit", "label": _("edit"), "view": "create_or_edit_buffer", "permissions": "input.change_buffer", }, {"name": "supplypath", "label": _("supply path"), "view": "supplypath_buffer"}, {"name": "whereused", "label": _("where used"), "view": "whereused_buffer"}, {"name": "plan", "label": _("plan"), "view": "output_buffer_plandetail"}, { "name": "plandetail", "label": _("plan detail"), "view": "input_operationplanmaterial_plandetail_by_buffer", }, { "name": "constraint", "label": _("constrained demand"), "view": "output_constraint_buffer", }, { "name": "messages", "label": _("messages"), "view": "admin:input_buffer_comment", }, ]
class PurchaseOrder_admin(MultiDBModelAdmin): model = PurchaseOrder raw_id_fields = ("item", "supplier") save_on_top = True fieldsets = ( ( None, { "fields": [ "reference", "item", "location", "supplier", "quantity", "ordering_date", "receipt_date", "status", "batch", ] + [a[0] for a in getAttributes(PurchaseOrder) if a[3]] }, ), ) exclude = ( "type", "source", "criticality", "delay", "operation", "owner", "color", "origin", "destination", "demand", "name", "due", "startdate", "enddate", ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_purchaseorder_change", "permissions": "input.change_purchaseorder", } ]
def getAttributeAPIFilterDefinition(cls): flt = {} for fld in getAttributes(cls): if fld[2] in ( "number", "integer", "date", "datetime", "duration", "time", ): flt[fld[0]] = ["exact", "in", "gt", "gte", "lt", "lte"] elif fld[2] == "string": flt[fld[0]] = ["exact", "in", "contains"] elif fld[2] == "boolean": flt[fld[0]] = [ "exact", ] return flt
class ItemDistribution_admin(MultiDBModelAdmin): model = ItemDistribution save_on_top = True raw_id_fields = ("item", "resource") fieldsets = ( (None, { "fields": ("item", "location", "origin", "leadtime") }), ( _("advanced"), { "fields": [ "sizeminimum", "sizemultiple", "sizemaximum", "batchwindow", "cost", "priority", "fence", "effective_start", "effective_end", "resource", "resource_qty", ] + [a[0] for a in getAttributes(ItemDistribution) if a[3]], "classes": ("collapse", ), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_itemdistribution_change", "permissions": "input.change_itemdistribution", }, { "name": "messages", "label": _("messages"), "view": "admin:input_itemdistribution_comment", }, ]
class OperationResource_admin(MultiDBModelAdmin): model = OperationResource raw_id_fields = ("operation", "resource", "skill") save_on_top = True exclude = ("id", ) fieldsets = ( (None, { "fields": ("operation", "resource", "quantity") }), ( _("Advanced"), { "fields": [ "skill", "setup", "quantity_fixed", "effective_start", "effective_end", "name", "priority", "search", ] + [a[0] for a in getAttributes(OperationResource) if a[3]], "classes": ("collapse", ), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_operationresource_change", "permissions": "input.change_operationresource", }, { "name": "messages", "label": _("messages"), "view": "admin:input_operationresource_comment", }, ]
class OperationMaterial_admin(MultiDBModelAdmin): model = OperationMaterial raw_id_fields = ("operation", "item") save_on_top = True exclude = ("id", ) fieldsets = ( (None, { "fields": ("operation", "item", "type", "quantity") }), ( _("advanced"), { "fields": [ "quantity_fixed", "transferbatch", "offset", "effective_start", "effective_end", "name", "priority", "search", ] + [a[0] for a in getAttributes(OperationMaterial) if a[3]], "classes": ("collapse", ), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_operationmaterial_change", "permissions": "input.change_operationmaterial", }, { "name": "messages", "label": _("messages"), "view": "admin:input_operationmaterial_comment", }, ]
def run(cls, database=DEFAULT_DB_ALIAS, **kwargs): import frepple if cls.filter: filter_and = "and %s " % cls.filter filter_where = "where %s " % cls.filter else: filter_and = "" filter_where = "" with connections[database].chunked_cursor() as cursor: cnt = 0 starttime = time() attrs = [ f[0] for f in getAttributes(Item) ] if attrs: attrsql = ', %s' % ', '.join(attrs) else: attrsql = '' cursor.execute(''' SELECT name, description, owner_id, cost, category, subcategory, source %s FROM item %s ''' % (attrsql, filter_where)) for i in cursor: cnt += 1 try: x = frepple.item(name=i[0], description=i[1], category=i[4], subcategory=i[5], source=i[6]) if i[2]: x.owner = frepple.item(name=i[2]) if i[3]: x.cost = i[3] idx = 7 for a in attrs: setattr(x, a, i[idx]) idx += 1 except Exception as e: logger.error("**** %s ****" % e) logger.info('Loaded %d items in %.2f seconds' % (cnt, time() - starttime))
def getAttributeAPIFields(cls): return tuple(i[0] for i in getAttributes(cls))
def run(cls, cluster=-1, database=DEFAULT_DB_ALIAS, **kwargs): cls.attrs = [ x for x in getAttributes(OperationPlan) if x[0] != "forecast" ] # Export operationplans to a temporary table cursor = connections[database].cursor() sql = """ create temporary table tmp_operationplan ( name character varying(1000), type character varying(5) NOT NULL, status character varying(20), quantity numeric(20,8) NOT NULL, startdate timestamp with time zone, enddate timestamp with time zone, criticality numeric(20,8), delay numeric, plan jsonb, source character varying(300), lastmodified timestamp with time zone NOT NULL, operation_id character varying(300), owner_id character varying(300), item_id character varying(300), destination_id character varying(300), origin_id character varying(300), location_id character varying(300), supplier_id character varying(300), demand_id character varying(300), due timestamp with time zone, color numeric(20,8), reference character varying(300) NOT NULL, batch character varying(300), quantity_completed numeric(20,8) """ for attr in cls.attrs: if attr[2] == "boolean": sql += ", %s boolean" % attr[0] elif attr[2] == "duration": sql += ", %s interval" % attr[0] elif attr[2] == "integer": sql += ", %s integer" % attr[0] elif attr[2] == "number": sql += ", %s numeric(15,6)" % attr[0] elif attr[2] == "string": sql += ", %s character varying(300)" % attr[0] elif attr[2] == "time": sql += ", %s time without time zone" % attr[0] elif attr[2] == "date": sql += ", %s date" % attr[0] elif attr[2] == "datetime": sql += ", %s timestamp with time zone" % attr[0] else: raise Exception("Unknown attribute type %s" % attr[2]) sql += ")" cursor.execute(sql) cursor.copy_from( CopyFromGenerator( cls.getData( cls.parent.timestamp, cluster=cluster, accepted_status=[ "confirmed", "approved", "completed", "closed" ], )), table="tmp_operationplan", size=1024, sep="\v", ) forecastfield0 = "" forecastfield1 = "" # Merge temp table into the actual table sql = (""" update operationplan set name=tmp.name, type=tmp.type, status=tmp.status, quantity=tmp.quantity, startdate=tmp.startdate, enddate=tmp.enddate, criticality=tmp.criticality, delay=tmp.delay * interval '1 second', plan=tmp.plan, source=tmp.source, lastmodified=tmp.lastmodified, operation_id=tmp.operation_id, owner_id=tmp.owner_id, item_id=tmp.item_id, destination_id=tmp.destination_id, origin_id=tmp.origin_id, location_id=tmp.location_id, supplier_id=tmp.supplier_id, demand_id=tmp.demand_id, due=tmp.due,%s color=tmp.color, batch=tmp.batch, quantity_completed=tmp.quantity_completed """ % forecastfield0) for a in cls.attrs: sql += ", %s=tmp.%s" % (a[0], a[0]) sql += """ from tmp_operationplan as tmp where operationplan.reference = tmp.reference """ cursor.execute(sql) # Make sure any deleted confirmed MO from Plan Editor gets deleted in the database # Only MO can currently be deleted through Plan Editor cursor.execute(""" delete from operationplan where status in ('confirmed','approved','completed','closed') and type = 'MO' and not exists (select 1 from tmp_operationplan where reference = operationplan.reference) """) cursor.execute(""" insert into operationplan (name,type,status,quantity,startdate,enddate, criticality,delay,plan,source,lastmodified, operation_id,owner_id, item_id,destination_id,origin_id, location_id,supplier_id, demand_id,due,color,reference,batch,quantity_completed%s) select name,type,status,quantity,startdate,enddate, criticality,delay * interval '1 second',plan,source,lastmodified, operation_id,owner_id, item_id,destination_id,origin_id, location_id,supplier_id, demand_id,due,color,reference,batch,quantity_completed%s from tmp_operationplan where not exists ( select 1 from operationplan where operationplan.reference = tmp_operationplan.reference ); """ % (forecastfield1, forecastfield1)) # directly injecting proposed records in operationplan table cursor.copy_from( CopyFromGenerator( cls.getData( cls.parent.timestamp, cluster=cluster, accepted_status=["proposed"], )), table="operationplan", size=1024, sep="\v", columns=[ "name", "type", "status", "quantity", "startdate", "enddate", "criticality", "delay", "plan", "source", "lastmodified", "operation_id", "owner_id", "item_id", "destination_id", "origin_id", "location_id", "supplier_id", "demand_id", "due", "color", "reference", "batch", "quantity_completed", ] + [a[0] for a in cls.attrs], ) # update demand table specific fields cursor.execute(""" with cte as ( select demand_id, sum(quantity) plannedquantity, max(enddate) deliverydate, max(enddate)-due as delay from operationplan where demand_id is not null and owner_id is null group by demand_id, due ) update demand set delay = cte.delay, plannedquantity = cte.plannedquantity, deliverydate = cte.deliverydate from cte where cte.demand_id = demand.name """) cursor.execute(""" update demand set delay = null, plannedquantity = null, deliverydate = null where (delay is not null or plannedquantity is not null or deliverydate is not null) and not exists( select 1 from operationplan where owner_id is null and operationplan.demand_id = demand.name ) """) cursor.execute(""" update demand set plannedquantity = 0 where status in ('open','quote') and plannedquantity is null """)
class Operation_admin(MultiDBModelAdmin): model = Operation raw_id_fields = ("item", "available", "owner") save_on_top = True fieldsets = ( ( None, { "fields": ( "name", "type", "item", "location", "duration", "duration_per", "owner", ) }, ), ( _("advanced"), { "fields": [ "description", "category", "subcategory", "fence", "posttime", "sizeminimum", "sizemultiple", "sizemaximum", "cost", "available", "priority", "search", "effective_start", "effective_end", ] + [a[0] for a in getAttributes(Operation) if a[3]], "classes": ("collapse",), }, ), ) tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_operation_change", "permissions": "input.change_operation", }, { "name": "supplypath", "label": _("supply path"), "view": "supplypath_operation", }, {"name": "whereused", "label": _("where used"), "view": "whereused_operation"}, {"name": "plan", "label": _("plan"), "view": "output_operation_plandetail"}, { "name": "plandetail", "label": _("manufacturing orders"), "view": "input_manufacturingorder_by_operation", }, { "name": "constraint", "label": _("constrained demand"), "view": "output_constraint_operation", }, { "name": "messages", "label": _("messages"), "view": "admin:input_operation_comment", }, ]
def getAttributeAPIReadOnlyFields(cls): return tuple(i[0] for i in getAttributes(cls) if not i[3])
class Resource_admin(MultiDBModelAdmin): model = Resource raw_id_fields = ( "maximum_calendar", "location", "setupmatrix", "owner", "available", "efficiency_calendar", ) fieldsets = ( (None, {"fields": ("name", "location", "type", "maximum")}), ( _("advanced"), { "fields": [ "description", "category", "subcategory", "constrained", "owner", "maximum_calendar", "available", "cost", "maxearly", "setupmatrix", "efficiency", "efficiency_calendar", ] + [a[0] for a in getAttributes(Resource) if a[3]], "classes": ("collapse",), }, ), ) save_on_top = True tabs = [ { "name": "edit", "label": _("edit"), "view": "admin:input_resource_change", "permissions": "input.change_resource", }, { "name": "supplypath", "label": _("supply path"), "view": "supplypath_resource", }, {"name": "whereused", "label": _("where used"), "view": "whereused_resource"}, {"name": "plan", "label": _("plan"), "view": "output_resource_plandetail"}, { "name": "plandetail", "label": _("plan detail"), "view": "input_operationplanresource_plandetail", }, { "name": "constraint", "label": _("constrained demand"), "view": "output_constraint_resource", }, { "name": "messages", "label": _("messages"), "view": "admin:input_resource_comment", }, ]