Zmodyfikuj plik printer-posnet-card.vue, aby był zgodny z printer-posnet.ts. Powinien on obsługiwać również pola name i isActive dziedziczone z GenericNamedGuidEntity. Pola te oraz pole organizationUnitId powinny być obsługiwane w taki sam sposób jak w pliku hospital-ward.ts.

/// printer-posnet.ts

import { GenericNamedGuidEntity } from "@/views/commerce/common/named-item";
import PrinterPosnetTarget from "@/views/commerce/printers-posnet/printer-posnet-target";

export default class PrinterPosnet extends GenericNamedGuidEntity{
  printerId: string | null = null;
  ipAddress: string | null = null;
  target: PrinterPosnetTarget = PrinterPosnetTarget.instance.reception;
  organizationUnitId: number;

  public static fromDto(dto: any): PrinterPosnet {
    const entity = new PrinterPosnet();
    entity.readDto(dto);
    return entity;
  }

  public static empty(): PrinterPosnet {
    const entity = new PrinterPosnet();
    return entity;
  }

  protected readDto(dto: any) {
    super.readDto(dto);
    this.printerId = dto.printerId;
    this.ipAddress = dto.ipAddress;
    this.target = PrinterPosnetTarget.getById(dto.target);
    this.organizationUnitId = dto.organizationUnitId;
  }

  get displayName() {
    return `${this.name} (${this.id})`;
  }

  get dto(): any {
    return {
      id: this.id,
      name: this.name,
      isActive: this.isActive,
      printerId: this.printerId,
      ipAddress: this.ipAddress,
      organizationUnitId: this.organizationUnitId,
      target: this.target.id
    };
  }
}

/// hospital-ward.ts

import { GenericNamedGuidEntity } from "@/views/commerce/common/named-item";
import HospitalWardMedicalService from "@/views/commerce/hospital/config/hospital-ward-medical-service";
import HospitalTreatmentType from "@/views/commerce/hospital/config/hospital-treatment-type";
import SpecializationScope from "@/views/commerce/specializations/specialization-scope";
import AttachmentData from "@/views/commerce/common/attachment-data";
import HospitalWardPrimaryService from "./dependent-services/hospital-ward-primary-service";
import ScheduleHoursRange from "@/views/commerce/common/schedule-hours/schedule-hours-range";
import MaskUtils from "@/components/enums/mask-utils";
import HospitalWardTreatmentOptions from "@/views/commerce/hospital/config/hospital-ward-treatment-options";
import HospitalWardMedicalServiceData from "@/views/commerce/hospital/config/hospital-ward-medical-service-data";

export default class HospitalWard extends GenericNamedGuidEntity {
  scope: number;
  organizationUnitId: number;
  specializationId: number | null;
  staffIds: number[] = [];
  capacity: number;
  intervalType: number;
  defaultIntervalCount: number | null = null;
  scheduleHours: ScheduleHoursRange = HospitalWard.defaultRange();
  attachments: AttachmentData = AttachmentData.empty();
  medicalServices: HospitalWardMedicalService[] = [];
  primaryServices: HospitalWardPrimaryService[] = [];
  treatmentTypes: HospitalTreatmentType[] = [];

  private static defaultRange(): ScheduleHoursRange {
    const entity = new ScheduleHoursRange();
    entity.fromHour = 8;
    entity.toHour = 14;
    return entity;
  }

  public static fromDto(dto: any) {
    const entity = new HospitalWard();
    entity.readDto(dto);
    return entity;
  }

  public static empty() {
    const entity = new HospitalWard();
    entity.scope = SpecializationScope.Commerce.id;
    return entity;
  }

  get scopeFormatted(): string {
    return SpecializationScope.getById(this.scope);
  }

  protected readDto(dto: any) {
    super.readDto(dto);
    this.capacity = dto.capacity;
    this.intervalType = dto.intervalType;
    this.defaultIntervalCount = dto.defaultIntervalCount;
    this.scheduleHours = dto.scheduleHours
      ? ScheduleHoursRange.fromBaseDto(dto.scheduleHours)
      : HospitalWard.defaultRange();
    this.attachments = dto.attachments
      ? AttachmentData.fromDto(dto.attachments)
      : AttachmentData.empty();
    this.scope = dto.scope;
    this.organizationUnitId = dto.organizationUnitId;
    this.specializationId = dto.specializationId;
    this.staffIds = dto.staffIds || [];
    this.medicalServices = dto.medicalServices?.map(HospitalWardMedicalService.fromDto) || [];
    this.treatmentTypes = dto.treatmentTypes?.map(HospitalTreatmentType.fromDto) || [];
    this.primaryServices = dto.primaryServices?.map(HospitalWardPrimaryService.fromDto) || [];
  }

  private get baseDto(): any {
    return {
      ...super.dto,
      scope: this.scope,
      scheduleHours: this.scheduleHours.dto,
      capacity: this.capacity,
      intervalType: this.intervalType,
      defaultIntervalCount: this.defaultIntervalCount,
      organizationUnitId: this.organizationUnitId,
      specializationId: this.specializationId
    };
  }

  public get medicalServicesData(): HospitalWardMedicalServiceData[] {
    const optionsMap = new Map<string, number>(
      this.treatmentTypes
        .filter(v => MaskUtils.hasFlag(v.options, HospitalWardTreatmentOptions.Primary))
        .map(v => [v.id!, v.options])
    );
    return this.medicalServices.map(
      v => new HospitalWardMedicalServiceData(v, optionsMap.get(v.hospitalTreatmentId) ?? 0)
    );
  }

  public get requestDto(): any {
    return {
      ...this.baseDto,
      attachments: this.attachments.requestDto
    };
  }

  public get dto(): any {
    return {
      ...this.baseDto,
      attachments: this.attachments.dto,
      staffIds: this.staffIds,
      medicalServices: this.medicalServices.map(v => v.dto),
      treatmentTypes: this.treatmentTypes.map(v => v.dto),
      primaryServices: this.primaryServices.map(v => v.dto)
    };
  }
}

/// printer-posnet-card.ts

<template>
  <titled-card :title="title" toolbar close-button @close="discard">
    <loading-container
      :is-loaded="isLoaded"
      fluid
      class="ma-1 pa-0 pr-3"
      style="min-width: min(700px, 95vw)">
      <v2-form :validator="formRef">
        <v-row dense>
          <v-col>
            <v2-text-field
              v-model="model.name"
              :rules="nameRules"
              :readonly="readonly"
              class="mb-2"
              label="Nazwa" />
          </v-col>
          <v-col>
            <v2-text-field
              v-model="model.ipAddress"
              :rules="ipAddressRules"
              :readonly="readonly"
              class="mb-2"
              label="Adres IP" />
          </v-col>
        </v-row>

        <v-row dense>
          <v-col>
            <v2-autocomplete
              v-model="model.target.id"
              :items="printerTargets"
              :readonly="readonly"
              label="Miejsce przeznaczenia"
              placeholder="Wybierz z listy" />
          </v-col>
          <v-col>
            <v2-switch
              v-model="model.isActive"
              :disabled="readonly"
              label="Aktywny" />
          </v-col>
        </v-row>

        <v-row justify="end">
          <v-col cols="auto">
            <submit-discard-async-buttons :submit="submit" @discard="discard" />
          </v-col>
        </v-row>
      </v2-form>
    </loading-container>
  </titled-card>
</template>

<script lang="ts">
import { computed, defineComponent, onMounted, ref } from "@vue/composition-api";
import LoadingContainer from "@/components/loading/loading-container.vue";
import SubmitDiscardAsyncButtons from "@/components/action-buttons/submit-discard-async-buttons.vue";
import axios from "@/lib/axios";
import TitledCard from "@/components/simple/titled-card.vue";
import { RulesUtils } from "@/lib/rules-utils";
import PrinterPosnetTarget from "@/views/commerce/printers-posnet/printer-posnet-target";
import V2Form from "@/compatibility-layer/components/v2-form.vue";
import V2TextField from "@/compatibility-layer/components/v2-text-field.vue";
import V2Autocomplete from "@/compatibility-layer/components/v2-autocomplete.vue";
import V2Select from "@/compatibility-layer/components/v2-select.vue";
import V2FormValidator from "@/compatibility-layer/components/v2-form-validator";
import PrinterPosnet from "@/views/commerce/printers-posnet/printer-posnet";

const PrinterPosnetCard = defineComponent({
  components: {
    TitledCard,
    SubmitDiscardAsyncButtons,
    V2Autocomplete,
    V2TextField,
    V2Form,
    V2Select,
    LoadingContainer
  },

  props: {
    value: {
      type: String,
      required: false,
      default: null
    },

    readonly: {
      type: Boolean,
      required: false,
      default: false
    }
  },

  emits: ["close"],

  setup(props, context) {
    const isLoaded = ref(false);
    const model = ref(props.value ? PrinterPosnet.fromDto({}) : PrinterPosnet.empty());
    const formRef = ref(V2FormValidator.create());

    const printerTargets = ref(PrinterPosnetTarget.All);

    onMounted(async () => {
      await loadData();
    });

    const loadData = async () => {
      if (props.value) {
        const response = await axios.get("/api/services/app/PrinterPosnet/GetPrinter", {
          params: { id: props.value }
        });
        model.value = PrinterPosnet.fromDto(response.data.result);
      }

      isLoaded.value = true;
    };

    const isNew = computed(() => !props.value);

    const submit = async () => {
      if (!formRef.value.validate()) return;

      if (isNew.value) {
        await axios.post("/api/services/app/PrinterPosnet/CreatePrinter", model.value.dto);
      } else {
        await axios.put("/api/services/app/PrinterPosnet/UpdatePrinter", model.value.dto);
      }

      context.emit("close", true);
    };

    const title = computed(() => {
      const prefix = "Zarządzanie Drukarkami Posnet";
      const suffix = isNew.value ? "Nowa drukarka" : `Edycja drukarki: ${model.value.name}`;
      return `${prefix} - ${suffix}`;
    });

    const nameRules = RulesUtils.MandatoryString(128);
    const modelRules = RulesUtils.MandatoryString(64);
    const ipAddressRules = [
      v => /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/.test(v) || "Niepoprawny adres IP"
    ];
    const portRules = [
      v => /^\d+$/.test(v) || "Port musi być liczbą",
      v => Number(v) > 0 && Number(v) < 65536 || "Port musi być w zakresie 1-65535"
    ];
    const orgUnitIdRules = [
      v => (!!v && Number(v) > 0) || "Niepoprawne ID jednostki organizacyjnej"
    ];

    return {
      isLoaded,
      model,
      formRef,
      submit,
      discard: () => context.emit("close", false),
      nameRules,
      modelRules,
      ipAddressRules,
      portRules,
      orgUnitIdRules,
      printerTargets: printerTargets.value,
      title,
      isNew
    };
  }
});

export default PrinterPosnetCard;
</script>