/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
package org.eclipse.osbp.dsl.tests.model.payment;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import java.util.Date;

import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess;
import org.eclipse.osbp.dsl.dto.lib.services.IDTOService;
import org.eclipse.osbp.dsl.tests.model.AbstractJPATest;
import org.junit.Test;
import org.osbp.mysmartshop.dtos.CashPositionDto;
import org.osbp.mysmartshop.dtos.CashRegisterDto;
import org.osbp.mysmartshop.dtos.CashSlipDto;
import org.osbp.mysmartshop.dtos.McustomerDto;

@SuppressWarnings("restriction")
public class CashTests extends AbstractJPATest {

	private IDTOService<McustomerDto> customerService;
	private IDTOService<CashRegisterDto> cashRegisterService;
	private IDTOService<CashSlipDto> cashSlipService;
	private IDTOService<CashPositionDto> cashSlipPosService;

	@Override
	public void setUp() throws Exception {
		super.setUp();

		customerService = DtoServiceAccess.getService(McustomerDto.class);
		cashRegisterService = DtoServiceAccess
				.getService(CashRegisterDto.class);
		cashSlipService = DtoServiceAccess.getService(CashSlipDto.class);
		cashSlipPosService = DtoServiceAccess.getService(CashPositionDto.class);
	}

	@Test
	public void testPersistCash() throws Exception {
		setUp();

		int custId = 10;

		// create customer
		McustomerDto cust1 = new McustomerDto();
		cust1.setId(custId);
		cust1.setFullname("customer1");
		customerService.update(cust1);
		cust1 = customerService.get(custId);

		CashRegisterDto cashRegister = new CashRegisterDto();
		cashRegister.setNum("1000");
		cashRegisterService.update(cashRegister);
		cashRegister = cashRegisterService.get(cashRegister.getId());

		CashSlipDto slip = new CashSlipDto();
		slip.setCashier("Jörg");
		slip.setCustomer(cust1);
		slip.setNow(new Date());
		slip.setCurrentDay(new Date().toString());
		slip.setSerial(10l);
		// slip.setRegister(cashRegister);
		slip.setTotal(100d);
		cashSlipService.update(slip);
		slip = cashSlipService.get(slip.getId());

		CashPositionDto pos1 = new CashPositionDto();
		pos1.setPrice(1000d);
		pos1.setQuantity(10d);
		slip.addToPositions(pos1);
		cashSlipPosService.update(pos1);

		slip = cashSlipService.get(slip.getId());
		assertEquals(1, slip.getPositions().size());

		cust1 = customerService.get(custId);
		assertEquals(1, cust1.getSlips().size());

		// remove the slip position
		slip.removeFromPositions(slip.getPositions().get(0));
		cashSlipService.update(slip);
		slip = cashSlipService.get(slip.getId());
		assertEquals(0, slip.getPositions().size());

		slip.setCustomer(null);
		cashSlipService.update(slip);

		slip = cashSlipService.get(slip.getId());
		assertNotNull(slip);
		assertNull(slip.getCustomer());

		cust1 = customerService.get(custId);
		assertEquals(0, cust1.getSlips().size());

	}

	@Test
	public void testCascade_OneToMany_AddAndPersistDetail() throws Exception {
		setUp();

		int custId = 11;

		// create customer
		McustomerDto cust1 = new McustomerDto();
		cust1.setId(custId);
		cust1.setFullname("customer1");
		customerService.update(cust1);
		cust1 = customerService.get(custId);

		CashSlipDto slip = new CashSlipDto();
		slip.setCashier("Jörg");
		slip.setCustomer(cust1);
		slip.setNow(new Date());
		slip.setCurrentDay(new Date().toString());
		slip.setSerial(10l);
		slip.setTotal(100d);
		cashSlipService.update(slip);

		// Test slip has not positions
		slip = cashSlipService.get(slip.getId());
		assertEquals(0, slip.getPositions().size());

		// UPDATE position by positionService
		CashPositionDto pos1 = new CashPositionDto();
		pos1.setPrice(1000d);
		pos1.setQuantity(10d);
		slip.addToPositions(pos1);
		cashSlipPosService.update(pos1);

		// Test that slip was also updated
		slip = cashSlipService.get(slip.getId());
		assertEquals(1, slip.getPositions().size());

		// DELETE position by positionService
		cashSlipPosService.delete(pos1);

		// Test that slip was also updated
		slip = cashSlipService.get(slip.getId());
		assertEquals(0, slip.getPositions().size());
	}

	@Test
	public void testCascade_OneToMany_AddAndPersistContainer() throws Exception {
		setUp();

		int custId = 15;

		// create customer
		McustomerDto cust1 = new McustomerDto();
		cust1.setId(custId);
		cust1.setFullname("customer1");
		customerService.update(cust1);
		cust1 = customerService.get(custId);

		CashSlipDto slip = new CashSlipDto();
		slip.setCashier("Jörg");
		slip.setCustomer(cust1);
		slip.setNow(new Date());
		slip.setCurrentDay(new Date().toString());
		slip.setSerial(10l);
		slip.setTotal(100d);

		CashPositionDto pos1 = new CashPositionDto();
		pos1.setPrice(1000d);
		pos1.setQuantity(10d);
		slip.addToPositions(pos1);

		CashPositionDto pos2 = new CashPositionDto();
		pos2.setPrice(1000d);
		pos2.setQuantity(10d);
		slip.addToPositions(pos2);

		cashSlipService.update(slip);
		slip = cashSlipService.get(slip.getId());
		assertEquals(2, slip.getPositions().size());

		// remove a position
		slip.removeFromPositions(slip.getPositions().get(0));

		cashSlipService.update(slip);
		// Test that slip was also updated
		slip = cashSlipService.get(slip.getId());
		assertEquals(1, slip.getPositions().size());

		// remove a position and add a new one
		slip.removeFromPositions(slip.getPositions().get(0));

		CashPositionDto pos3 = new CashPositionDto();
		pos3.setPrice(1000d);
		pos3.setQuantity(10d);
		slip.addToPositions(pos3);

		cashSlipService.update(slip);

		slip = cashSlipService.get(slip.getId());
		assertEquals(1, slip.getPositions().size());
		assertEquals(pos3.getId(), slip.getPositions().get(0).getId());
	}

	@Test
	public void testManyToOne__setToNull() throws Exception {
		setUp();

		int custId = 12;

		// create customer
		McustomerDto cust1 = new McustomerDto();
		cust1.setId(custId);
		cust1.setFullname("customer1");
		customerService.update(cust1);
		cust1 = customerService.get(custId);

		CashSlipDto slip = new CashSlipDto();
		slip.setCashier("Jörg");
		slip.setCustomer(cust1);
		slip.setNow(new Date());
		slip.setCurrentDay(new Date().toString());
		slip.setSerial(10l);
		slip.setTotal(100d);

		CashPositionDto pos1 = new CashPositionDto();
		pos1.setPrice(1000d);
		pos1.setQuantity(10d);
		slip.addToPositions(pos1);

		cashSlipService.update(slip);
		slip = cashSlipService.get(slip.getId());
		assertEquals(1, slip.getPositions().size());

		cust1 = customerService.get(custId);
		assertEquals(1, cust1.getSlips().size());

		// set the customer to null and update slip
		slip.setCustomer(null);
		cashSlipService.update(slip);

		// test that the slip was removed from customer
		cust1 = customerService.get(custId);
		assertEquals(0, cust1.getSlips().size());

		slip = cashSlipService.get(slip.getId());
		assertNotNull(slip);
		assertNull(slip.getCustomer());

	}

	@Test
	public void errorRequired__testManyToOne__removeFromList() throws Exception {
		setUp();

		int custId = 13;

		// create customer
		McustomerDto cust1 = new McustomerDto();
		cust1.setId(custId);
		cust1.setFullname("customer1");
		customerService.update(cust1);
		cust1 = customerService.get(custId);

		CashSlipDto slip = new CashSlipDto();
		slip.setCashier("Jörg");
		slip.setCustomer(cust1);
		slip.setNow(new Date());
		slip.setCurrentDay(new Date().toString());
		slip.setSerial(10l);
		slip.setTotal(100d);

		CashPositionDto pos1 = new CashPositionDto();
		pos1.setPrice(1000d);
		pos1.setQuantity(10d);
		slip.addToPositions(pos1);

		cashSlipService.update(slip);
		slip = cashSlipService.get(slip.getId());
		assertEquals(1, slip.getPositions().size());

		cust1 = customerService.get(custId);
		assertEquals(1, cust1.getSlips().size());

		// set the customer to null and update slip
		cust1.removeFromSlips(cust1.internalGetSlips().get(0));
		customerService.update(cust1);

		slip = cashSlipService.get(slip.getId());
		assertNotNull(slip);

		/*
		 * ATTENTION!!! This is expected, since removing a slip from a customer
		 * and updating the customer has no effect!!
		 */
		try {
			assertNull(slip.getCustomer());
			fail();
		} catch (AssertionError e) {
			// expected
		}

		try {
			cust1 = customerService.get(custId);
			assertEquals(0, cust1.getSlips().size());
		} catch (AssertionError e) {
			// expected
		}
	}

}
