package org.estatio.canonical.invoice;

import java.util.Optional;
import java.util.SortedSet;

import javax.inject.Inject;

import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;

import org.estatio.canonical.DtoFactoryAbstract;
import org.estatio.canonical.invoice.v1.InvoiceItemDto;
import org.estatio.dom.DtoMappingHelper;
import org.estatio.dom.charge.Charge;
import org.estatio.dom.invoice.InvoiceItem;
import org.estatio.dom.lease.Occupancy;
import org.estatio.dom.tax.Tax;

@DomainService(
        nature = NatureOfService.DOMAIN
)
public class InvoiceItemDtoFactory extends DtoFactoryAbstract {

    @Programmatic
    public InvoiceItemDto newDto(final InvoiceItem item) {
        InvoiceItemDto dto = new InvoiceItemDto();

        final Charge charge = item.getCharge();
        dto.setChargeReference(charge.getReference());
        dto.setChargeDescription(charge.getDescription());
        dto.setChargeExternalReference(charge.getExternalReference());
        dto.setChargeName(charge.getName());

        final Tax tax = item.getTax();
        dto.setTaxReference(tax.getReference());
        dto.setTaxName(tax.getName());
        dto.setTaxDescription(tax.getDescription());
        dto.setTaxExternalReference(tax.getExternalReference());

        dto.setNetAmount(item.getNetAmount());
        dto.setGrossAmount(item.getGrossAmount());
        dto.setVatAmount(item.getVatAmount());

        dto.setDescription(item.getDescription());

        dto.setStartDate(asXMLGregorianCalendar(item.getStartDate()));
        dto.setEndDate(asXMLGregorianCalendar(item.getEndDate()));
        dto.setEffectiveStartDate(asXMLGregorianCalendar(item.getEffectiveStartDate()));
        dto.setEffectiveEndDate(asXMLGregorianCalendar(item.getEffectiveEndDate()));

        final SortedSet<Occupancy> occupancies = item.getInvoice().getLease().getOccupancies();
        final Optional<Occupancy> occupancyIfAny =
                occupancies.stream().filter(x -> x.getInterval().contains(item.getDueDate())).findFirst();
        dto.setOccupancyBrand(occupancyIfAny.isPresent()? occupancyIfAny.get().getBrand().getName(): null);

        return dto;
    }

    @Inject
    DtoMappingHelper mappingHelper;
}

@@ -516,16 +516,52 @@
 ceItem;%0A
+import org.estatio.dom.lease.Lease;%0A
 import o
@@ -1909,24 +1909,124 @@
 dDate()));%0A%0A
+        final Lease leaseIfAny = item.getInvoice().getLease();%0A        if(leaseIfAny != null) %7B%0A    
         fina
@@ -2066,36 +2066,18 @@
 s = 
-item.getInvoice().getLease()
+leaseIfAny
 .get
@@ -2087,24 +2087,28 @@
 upancies();%0A
+    
         fina
@@ -2162,16 +2162,20 @@
         
+    
 occupanc
@@ -2261,24 +2261,28 @@
 ();%0A        
+ 
+   
 dto.setOccup
@@ -2317,16 +2317,17 @@
 resent()
+ 
 ? occupa
@@ -2361,16 +2361,17 @@
 etName()
+ 
 : null);
@@ -2371,16 +2371,25 @@
  null);%0A
+        %7D
 %0A       

add guard to InvoiceItemDtoFactory to only attempt to set the occupancy brand if a lease item is available.