diff --git a/seed/migrations/0237_auto_20241106_1339.py b/seed/migrations/0237_auto_20241106_1339.py new file mode 100644 index 0000000000..f835cd64e5 --- /dev/null +++ b/seed/migrations/0237_auto_20241106_1339.py @@ -0,0 +1,91 @@ +# Generated by Django 3.2.25 on 2024-11-06 21:39 + +import quantityfield.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("seed", "0236_auto_20241030_1434"), + ] + + operations = [ + migrations.AlterField( + model_name="batterysystem", + name="efficiency", + field=models.FloatField(), + ), + migrations.AlterField( + model_name="meter", + name="connection_type", + field=models.IntegerField( + choices=[ + (1, "Imported"), + (2, "Exported"), + (3, "Receiving Service"), + (4, "Returning To Service"), + (5, "Total From Users"), + (6, "Total To Users"), + ], + default=1, + ), + ), + migrations.AlterField( + model_name="service", + name="emission_factor", + field=models.FloatField(null=True), + ), + migrations.RemoveField( + model_name="batterysystem", + name="capacity", + ), + migrations.RemoveField( + model_name="dessystem", + name="capacity", + ), + migrations.AddField( + model_name="batterysystem", + name="energy_capacity", + field=quantityfield.fields.QuantityField(base_units="kWh", default=1, unit_choices=["kWh"]), + preserve_default=False, + ), + migrations.AddField( + model_name="batterysystem", + name="power_capacity", + field=quantityfield.fields.QuantityField(base_units="kW", default=1, unit_choices=["kW"]), + preserve_default=False, + ), + migrations.AddField( + model_name="dessystem", + name="cooling_capacity", + field=quantityfield.fields.QuantityField(base_units="Ton", null=True, unit_choices=["Ton"]), + ), + migrations.AddField( + model_name="dessystem", + name="heating_capacity", + field=quantityfield.fields.QuantityField(base_units="MMBtu", null=True, unit_choices=["MMBtu"]), + ), + migrations.AddField( + model_name="evsesystem", + name="voltage", + field=quantityfield.fields.QuantityField(base_units="V", default=1, unit_choices=["V"]), + preserve_default=False, + ), + migrations.AlterField( + model_name="batterysystem", + name="voltage", + field=quantityfield.fields.QuantityField(base_units="V", unit_choices=["V"]), + ), + migrations.AlterField( + model_name="evsesystem", + name="power", + field=quantityfield.fields.QuantityField(base_units="kW", unit_choices=["kW"]), + ), + migrations.AddConstraint( + model_name="dessystem", + constraint=models.CheckConstraint( + check=models.Q(("heating_capacity__isnull", False), ("cooling_capacity__isnull", False), _connector="OR"), + name="heating_or_cooling_capacity_required", + ), + ), + ] diff --git a/seed/models/meters.py b/seed/models/meters.py index 1003a447ba..934449e936 100644 --- a/seed/models/meters.py +++ b/seed/models/meters.py @@ -15,24 +15,24 @@ class Meter(models.Model): ## CONNECTION TYPES # These connection types do not require services. May be on a property or system - FROM_OUTSIDE = 1 # tracks what is received via an unknown source - TO_OUTSIDE = 2 # tracks what is expelled via an unknown source + IMPORTED = 1 # tracks what is received via an unknown source + EXPORTED = 2 # tracks what is expelled via an unknown source # These connection types require services. May be on a property or system - FROM_SERVICE_TO_PATRON = 3 # tracks what is received via my service - FROM_PATRON_TO_SERVICE = 4 # tracks what is expelled via my service + RECEIVING_SERVICE = 3 # tracks what is received via my service + RETURNING_TO_SERVICE = 4 # tracks what is expelled via my service # These connection types require services and may only be on Systems - TOTAL_FROM_PATRON = 5 # tracks everything that this system expelled via my service - TOTAL_TO_PATRON = 6 # tracks everything that this system received via my service + TOTAL_FROM_USERS = 5 # tracks everything that this system expelled via my service + TOTAL_TO_USERS = 6 # tracks everything that this system received via my service CONNECTION_TYPES = ( - (FROM_OUTSIDE, "From Outside"), - (TO_OUTSIDE, "To Outside"), - (FROM_SERVICE_TO_PATRON, "From Service To Patron"), - (FROM_PATRON_TO_SERVICE, "From Patron To Service"), - (TOTAL_FROM_PATRON, "Total From Patron"), - (TOTAL_TO_PATRON, "Total To Patron"), + (IMPORTED, "Imported"), + (EXPORTED, "Exported"), + (RECEIVING_SERVICE, "Receiving Service"), + (RETURNING_TO_SERVICE, "Returning To Service"), + (TOTAL_FROM_USERS, "Total From Users"), + (TOTAL_TO_USERS, "Total To Users"), ) COAL_ANTHRACITE = 1 @@ -165,7 +165,7 @@ class Meter(models.Model): type = models.IntegerField(choices=ENERGY_TYPES, default=None, null=True) service = models.ForeignKey("Service", on_delete=models.SET_NULL, related_name="meters", null=True, blank=True) - connection_type = models.IntegerField(choices=CONNECTION_TYPES, default=FROM_OUTSIDE, null=False) + connection_type = models.IntegerField(choices=CONNECTION_TYPES, default=IMPORTED, null=False) def copy_readings(self, source_meter, overlaps_possible=True): """ @@ -218,7 +218,7 @@ def presave_meter(sender, instance, **kwargs): if property is not None and system is not None: raise IntegrityError(f"Meter {instance.id} has both a property and a system. It must only have one.") - outside_connection = connection_type in [Meter.FROM_OUTSIDE, Meter.TO_OUTSIDE] + outside_connection = connection_type in [Meter.IMPORTED, Meter.EXPORTED] if outside_connection: # outside connections don't have services if instance.service is not None: @@ -228,7 +228,7 @@ def presave_meter(sender, instance, **kwargs): if service is None: raise IntegrityError(f"Meter {instance.id} has connection_type '{connection_string}', but is not connected to a service") - total_connections = connection_type in [Meter.TOTAL_FROM_PATRON, Meter.TOTAL_TO_PATRON] + total_connections = connection_type in [Meter.TOTAL_FROM_USERS, Meter.TOTAL_TO_USERS] if total_connections: # Only systems have connection type "total" if system is None: @@ -245,7 +245,7 @@ def presave_meter(sender, instance, **kwargs): if Meter.objects.filter(service=service, connection_type=connection_type).exclude(pk=instance.pk).exists(): raise IntegrityError(f"Service {service.id} already has a meter with connection type '{connection_string}'") - elif property: # Meter.FROM_PATRON_TO_SERVICE and Meter.FROM_SERVICE_TO_PATRON + elif property: # Meter.RETURNING_TO_SERVICE and Meter.RECEIVING_SERVICE # service must be within the meter's property's group property_groups = InventoryGroupMapping.objects.filter(property=property).values_list("group_id", flat=True) if service is not None and service.system.group.id not in property_groups: diff --git a/seed/models/systems.py b/seed/models/systems.py index 1d4964fbdc..6cdf0ffae4 100644 --- a/seed/models/systems.py +++ b/seed/models/systems.py @@ -4,10 +4,16 @@ """ from django.db import models +from django.db.models import Q from model_utils.managers import InheritanceManager +from quantityfield.fields import QuantityField +from quantityfield.units import ureg from seed.models import InventoryGroup +ureg.define("MMBtu = 1e6 * Btu") +ureg.define("Ton = 12000 * Btu / hour") + class System(models.Model): name = models.CharField(max_length=255) @@ -32,9 +38,17 @@ class DESSystem(System): (CHP, "CHP"), ) type = models.IntegerField(choices=DES_TYPES, null=False) - capacity = models.IntegerField(null=False) + heating_capacity = QuantityField("MMBtu", null=True) + cooling_capacity = QuantityField("Ton", null=True) count = models.IntegerField(default=1, null=False) + class Meta: + constraints = [ + models.CheckConstraint( + check=Q(heating_capacity__isnull=False) | Q(cooling_capacity__isnull=False), name="heating_or_cooling_capacity_required" + ) + ] + class EVSESystem(System): LEVEL1 = 0 @@ -47,20 +61,22 @@ class EVSESystem(System): (LEVEL3, "Level3-DC Fast"), ) type = models.IntegerField(choices=EVSE_TYPES, null=False) - power = models.IntegerField(null=False) + power = QuantityField("kW", null=False) + voltage = QuantityField("V", null=False) count = models.IntegerField(default=1, null=False) class BatterySystem(System): - efficiency = models.IntegerField(null=False) - capacity = models.IntegerField(null=False) - voltage = models.IntegerField(null=False) + efficiency = models.FloatField(null=False) + power_capacity = QuantityField("kW", null=False) + energy_capacity = QuantityField("kWh", null=False) + voltage = QuantityField("V", null=False) class Service(models.Model): system = models.ForeignKey(System, on_delete=models.CASCADE, related_name="services") name = models.CharField(max_length=255) - emission_factor = models.IntegerField(null=True) + emission_factor = models.FloatField(null=True) objects = InheritanceManager() diff --git a/seed/serializers/meters.py b/seed/serializers/meters.py index cc8434a774..e323d6a4bf 100644 --- a/seed/serializers/meters.py +++ b/seed/serializers/meters.py @@ -47,15 +47,12 @@ def validate_scenario_id(self, scenario_id): def to_representation(self, obj): result = super().to_representation(obj) - if obj.source == Meter.GREENBUTTON: result["source_id"] = usage_point_id(obj.source_id) - result["scenario_name"] = obj.scenario.name if obj.scenario else None - if obj.alias is None or obj.alias == "": result["alias"] = f"{obj.get_type_display()} - {obj.get_source_display()} - {result['source_id']}" - + self.get_property_display_name(obj, result) self.set_config(obj, result) return result @@ -63,12 +60,12 @@ def to_representation(self, obj): def set_config(self, obj, result): # generate config for meter modal connection_lookup = { - 1: {"direction": "inflow", "use": "outside", "connection": "outside"}, - 2: {"direction": "outflow", "use": "outside", "connection": "outside"}, - 3: {"direction": "inflow", "use": "using", "connection": "service"}, - 4: {"direction": "outflow", "use": "using", "connection": "service"}, - 5: {"direction": "inflow", "use": "offering", "connection": "service"}, - 6: {"direction": "outflow", "use": "offering", "connection": "service"}, + 1: {"direction": "imported", "use": "outside", "connection": "outside"}, + 2: {"direction": "exported", "use": "outside", "connection": "outside"}, + 3: {"direction": "imported", "use": "using", "connection": "service"}, + 4: {"direction": "exported", "use": "using", "connection": "service"}, + 5: {"direction": "imported", "use": "offering", "connection": "service"}, + 6: {"direction": "exported", "use": "offering", "connection": "service"}, } group_id, system_id = None, None @@ -80,3 +77,9 @@ def set_config(self, obj, result): config = {"group_id": group_id, "system_id": system_id, "service_id": obj.service_id, **connection_lookup[obj.connection_type]} result["config"] = config + + def get_property_display_name(self, obj, result): + if obj.property: + state = obj.property.views.first().state + property_display_field = state.organization.property_display_field + result["property_display_field"] = getattr(state, property_display_field, "Unknown") diff --git a/seed/serializers/pint.py b/seed/serializers/pint.py index b6347836e3..54287d4cbe 100644 --- a/seed/serializers/pint.py +++ b/seed/serializers/pint.py @@ -76,7 +76,8 @@ def collapse_unit(org, x): if isinstance(x, ureg.Quantity): dimensionality = get_dimensionality(x) - pint_spec = pint_specs[dimensionality] + # default to quantity's units if not found + pint_spec = pint_specs.get(dimensionality, x.units) converted_value = x.to(pint_spec).magnitude return round(converted_value, org.display_decimal_places) elif isinstance(x, list): diff --git a/seed/serializers/systems.py b/seed/serializers/systems.py index 33b6a27a39..f15d663d82 100644 --- a/seed/serializers/systems.py +++ b/seed/serializers/systems.py @@ -11,6 +11,7 @@ from seed.data_importer.utils import usage_point_id from seed.models import BatterySystem, DESSystem, EVSESystem, Service, System from seed.serializers.base import ChoiceField +from seed.serializers.pint import collapse_unit class ServiceSerializer(serializers.ModelSerializer): @@ -70,63 +71,62 @@ class Meta: fields = ["id", "name", "services", "type", "group_id"] def validate(self, data): - SystemClass = self.Meta.model id = self.instance.id if self.instance else None - if SystemClass.objects.filter(name=data.get("name"), group=data.get("group_id")).exclude(id=id).exists(): + if System.objects.filter(name=data.get("name"), group=data.get("group_id")).exclude(id=id).exists(): raise serializers.ValidationError("System name must be unique within group") return data class DESSystemSerializer(SystemSerializer): des_type = ChoiceField(source="type", choices=DESSystem.DES_TYPES) - capacity = serializers.IntegerField() - count = serializers.IntegerField() class Meta: model = DESSystem - fields = [*SystemSerializer.Meta.fields, "des_type", "capacity", "count"] + fields = [*SystemSerializer.Meta.fields, "cooling_capacity", "count", "des_type", "heating_capacity"] def to_representation(self, obj): + org = obj.group.organization + mode = "Cooling" if obj.cooling_capacity else "Heating" return { "type": "DES", "des_type": obj.get_type_display(), - "capacity": obj.capacity, + "cooling_capacity": collapse_unit(org, obj.cooling_capacity), "count": obj.count, + "heating_capacity": collapse_unit(org, obj.heating_capacity), + "mode": mode, } class EVSESystemSerializer(SystemSerializer): evse_type = ChoiceField(source="type", choices=EVSESystem.EVSE_TYPES) - power = serializers.IntegerField() - count = serializers.IntegerField() class Meta: model = EVSESystem - fields = [*SystemSerializer.Meta.fields, "evse_type", "power", "count"] + fields = [*SystemSerializer.Meta.fields, "count", "evse_type", "power", "voltage"] def to_representation(self, obj): + org = obj.group.organization return { "type": "EVSE", "evse_type": obj.get_type_display(), - "power": obj.power, - "count": obj.count, + "power": collapse_unit(org, obj.power), + "voltage": collapse_unit(org, obj.voltage), + "count": collapse_unit(org, obj.count), } class BatterySystemSerializer(SystemSerializer): - efficiency = serializers.IntegerField() - capacity = serializers.IntegerField() - voltage = serializers.IntegerField() - class Meta: model = BatterySystem - fields = [*SystemSerializer.Meta.fields, "efficiency", "capacity", "voltage"] + fields = [*SystemSerializer.Meta.fields, "energy_capacity", "power_capacity", "efficiency", "voltage"] def to_representation(self, obj): + org = obj.group.organization return { "type": "Battery", "efficiency": obj.efficiency, - "capacity": obj.capacity, - "voltage": obj.voltage, + "energy_capacity": collapse_unit(org, obj.energy_capacity), + "power_capacity": collapse_unit(org, obj.power_capacity), + "voltage": collapse_unit(org, obj.voltage), } diff --git a/seed/static/seed/js/controllers/inventory_detail_meters_controller.js b/seed/static/seed/js/controllers/inventory_detail_meters_controller.js index 747afc21f2..628ca16122 100644 --- a/seed/static/seed/js/controllers/inventory_detail_meters_controller.js +++ b/seed/static/seed/js/controllers/inventory_detail_meters_controller.js @@ -71,9 +71,9 @@ angular.module('SEED.controller.inventory_detail_meters', []).controller('invent // dont show edit if disabled? const buttons = ( '
' + - ' ' + ' ' + - ' ' + + // ' ' + + ' ' + '
' ); @@ -250,23 +250,8 @@ angular.module('SEED.controller.inventory_detail_meters', []).controller('invent // refresh_readings make an API call to refresh the base readings data // according to the selected interval $scope.refresh_meters_and_readings = () => { - spinner_utility.show(); - const get_meters_Promise = meter_service.get_meters($scope.inventory.view_id, $scope.organization.id); - const get_readings_Promise = meter_service.property_meter_usage( - $scope.inventory.view_id, - $scope.organization.id, - $scope.interval.selected, - [] // Not excluding any meters from the query - ); - Promise.all([get_meters_Promise, get_readings_Promise]).then((data) => { - // update the base data and reset filters - [meters, property_meter_usage] = data; - - resetSelections(); - $scope.meterGridApi.core.refresh(); - $scope.applyFilters(); - spinner_utility.hide(); - }); + // Any reason we can't just reload? Solves issues with null group_ids + $state.reload(); }; // refresh_readings make an API call to refresh the base readings data diff --git a/seed/static/seed/js/controllers/inventory_group_detail_meters_controller.js b/seed/static/seed/js/controllers/inventory_group_detail_meters_controller.js index 5c5e45b0b8..282c9d3b9e 100644 --- a/seed/static/seed/js/controllers/inventory_group_detail_meters_controller.js +++ b/seed/static/seed/js/controllers/inventory_group_detail_meters_controller.js @@ -20,6 +20,7 @@ angular.module('SEED.controller.inventory_group_detail_meters', []) 'urls', 'organization_payload', 'group', + 'columns', // eslint-disable-next-line func-names function ( $scope, @@ -37,7 +38,8 @@ angular.module('SEED.controller.inventory_group_detail_meters', []) property_meter_usage, urls, organization_payload, - group + group, + columns ) { // Ideally, these should be translatable, but the "selected" property // should always be in English as this gets sent to BE. @@ -58,6 +60,8 @@ angular.module('SEED.controller.inventory_group_detail_meters', []) $scope.organization = organization_payload.organization; $scope.filler_cycle = cycles.cycles[0].id; + const property_display_name = columns.find((col) => col.column_name === $scope.organization.property_display_field).display_name; + $scope.inventory = { view_id: $stateParams.view_id }; @@ -91,8 +95,8 @@ angular.module('SEED.controller.inventory_group_detail_meters', []) const buttons = ( '
' + - ' ' + ' ' + + ' ' + '
' ); @@ -111,7 +115,7 @@ angular.module('SEED.controller.inventory_group_detail_meters', []) { field: 'source_id' }, { field: 'scenario_id' }, { field: 'connection_type' }, - { field: 'property_id' }, + { field: 'property_display_field', displayName: property_display_name }, { field: 'system_name' }, { field: 'service_name', displayName: 'Connection', cellTemplate: '{$ row.entity.service_name $}' }, { field: 'is_virtual' }, diff --git a/seed/static/seed/js/controllers/inventory_group_detail_systems_controller.js b/seed/static/seed/js/controllers/inventory_group_detail_systems_controller.js index 5e5d8e86c1..b8e7943d85 100644 --- a/seed/static/seed/js/controllers/inventory_group_detail_systems_controller.js +++ b/seed/static/seed/js/controllers/inventory_group_detail_systems_controller.js @@ -10,7 +10,6 @@ angular.module('SEED.controller.inventory_group_detail_systems', []) '$timeout', '$uibModal', 'urls', - 'Notification', 'dataset_service', 'cycles', 'systems', @@ -24,7 +23,6 @@ angular.module('SEED.controller.inventory_group_detail_systems', []) $timeout, $uibModal, urls, - Notification, dataset_service, cycles, systems, @@ -35,25 +33,31 @@ angular.module('SEED.controller.inventory_group_detail_systems', []) $scope.group_id = $stateParams.group_id; $scope.inventory_display_name = group.name; $scope.systems = systems.data; - const all_systems = [...$scope.systems.DES ?? [], ...$scope.systems.EVSE ?? [], ...$scope.systems.Battery ?? []]; + const system_types = ['DES - Cooling', 'DES - Heating', 'EVSE', 'Battery']; + const all_systems = system_types.flatMap((type) => $scope.systems[type] ?? []); const org_id = organization_payload.organization.id; $scope.filler_cycle = cycles.cycles[0].id; $scope.system_tables = [ { - system_key: 'DES', - headers: ['Name', 'DES Type', 'Capacity', 'Count'], - fields: ['name', 'des_type', 'capacity', 'count'] + system_key: 'DES - Cooling', + headers: ['Name', 'DES Type', 'Capacity (Ton)', 'Count'], + fields: ['name', 'des_type', 'cooling_capacity', 'count'] + }, + { + system_key: 'DES - Heating', + headers: ['Name', 'DES Type', 'Capacity (MMBtu)', 'Count'], + fields: ['name', 'des_type', 'heating_capacity', 'count'] }, { system_key: 'EVSE', - headers: ['Name', 'EVSE Type', 'Power', 'Count'], - fields: ['name', 'evse_type', 'power', 'count'] + headers: ['Name', 'EVSE Type', 'Power (kW)', 'Voltage (V)', 'Count'], + fields: ['name', 'evse_type', 'power', 'voltage', 'count'] }, { system_key: 'Battery', - headers: ['Name', 'Efficiency', 'Capacity', 'Voltage'], - fields: ['name', 'efficiency', 'capacity', 'voltage'] + headers: ['Name', 'Efficiency (%)', 'Energy Capacity (kWh)', 'Power Capacity (kW)', 'Voltage (V)'], + fields: ['name', 'efficiency', 'energy_capacity', 'power_capacity', 'voltage'] } ]; @@ -120,13 +124,19 @@ angular.module('SEED.controller.inventory_group_detail_systems', []) } }); - modalInstance.result.finally(() => { - $state.reload().then(() => { - $timeout(() => { - expand_service(system); - }, 0); - }); - }); + modalInstance.result.then( + () => { + $state.reload().then(() => { + $timeout(() => { + expand_service(system); + }, 0); + }); + }, + () => { + console.log('here'); + // do nothing + } + ); }; const expand_service = (system) => { diff --git a/seed/static/seed/js/controllers/meter_edit_modal_controller.js b/seed/static/seed/js/controllers/meter_edit_modal_controller.js index 5ebcb6e0e1..91a6c556eb 100644 --- a/seed/static/seed/js/controllers/meter_edit_modal_controller.js +++ b/seed/static/seed/js/controllers/meter_edit_modal_controller.js @@ -87,8 +87,8 @@ angular.module('SEED.controller.meter_edit_modal', []).controller('meter_edit_mo }); $scope.direction_options = [ - { display: 'Flowing In', value: 'inflow' }, - { display: 'Flowing Out', value: 'outflow' } + { display: 'Imported', value: 'imported' }, + { display: 'Exported', value: 'exported' } ]; $scope.connection_options = [ { display: 'Connected to Outside', value: 'outside' }, diff --git a/seed/static/seed/js/controllers/system_modal_controller.js b/seed/static/seed/js/controllers/system_modal_controller.js index 401cc8c094..3ef490396c 100644 --- a/seed/static/seed/js/controllers/system_modal_controller.js +++ b/seed/static/seed/js/controllers/system_modal_controller.js @@ -36,6 +36,17 @@ angular.module('SEED.controller.system_modal', []).controller('system_modal_cont $scope.capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1); + $scope.change_des_type = () => { + if ($scope.system.des_type === 'Boiler') { + $scope.system.cooling_capacity = null; + } else { + $scope.system_heating_capacity = null; + } + }; + if ($scope.system.type === 'des') { + $scope.change_des_type(); + } + $scope.submitSystemForm = () => { if (action === 'create') { create_system(); @@ -53,9 +64,11 @@ angular.module('SEED.controller.system_modal', []).controller('system_modal_cont $uibModalInstance.close(); }, (response) => { - const errors = Object.values(response.data.errors); + let errors = response.data.errors; + if (typeof (errors) !== 'string') { + errors = Object.values(errors); + } Notification.error(`${errors}`); - $uibModalInstance.dismiss('cancel'); } ); }; diff --git a/seed/static/seed/js/controllers/update_inventory_groups_modal_controller.js b/seed/static/seed/js/controllers/update_inventory_groups_modal_controller.js index 8d3ffd0150..9443edb839 100644 --- a/seed/static/seed/js/controllers/update_inventory_groups_modal_controller.js +++ b/seed/static/seed/js/controllers/update_inventory_groups_modal_controller.js @@ -26,6 +26,7 @@ angular.module('SEED.controller.update_inventory_groups_modal', []) Notification ) { $scope.view_ids = view_ids; + $scope.num = view_ids.length; $scope.inventory_type = inventory_type; $scope.org_id = org_id; diff --git a/seed/static/seed/js/seed.js b/seed/static/seed/js/seed.js index a531d0a71c..56a4910857 100644 --- a/seed/static/seed/js/seed.js +++ b/seed/static/seed/js/seed.js @@ -2337,7 +2337,15 @@ '$stateParams', 'inventory_group_service', 'user_service', ($stateParams, inventory_group_service, user_service) => inventory_group_service.get_group(user_service.get_organization().id, $stateParams.group_id) ], - groups: () => null + columns: [ + '$stateParams', + 'inventory_service', + 'user_service', + ($stateParams, inventory_service, user_service) => { + const org_id = user_service.get_organization().id; + return inventory_service.get_property_column_names_for_org(org_id); + } + ] } }) .state({ diff --git a/seed/static/seed/partials/inventory_list.html b/seed/static/seed/partials/inventory_list.html index 0f12369b9b..c6aa566093 100644 --- a/seed/static/seed/partials/inventory_list.html +++ b/seed/static/seed/partials/inventory_list.html @@ -52,10 +52,15 @@

{$:: (group_id? 'Group - ': '')$}{$:: (inventory_type === 'taxlots' ? 'Tax L - - + + + + + + + + - - - - - - + + + - - - - + - +