/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2014 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.apps.account.service.invoice.workflow.cancel;

import java.math.BigDecimal;

import com.axelor.apps.account.db.Invoice;
import com.axelor.apps.account.db.Move;
import com.axelor.apps.account.db.repo.MoveRepository;
import com.axelor.apps.account.service.administration.GeneralServiceAccount;
import com.axelor.apps.account.service.invoice.workflow.WorkflowInvoice;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.IException;
import com.axelor.inject.Beans;

public class CancelState extends WorkflowInvoice {
	
	public CancelState(Invoice invoice){ super(invoice); }
	
	@Override
	public void process() throws AxelorException {
		
		if(invoice.getStatusSelect() == STATUS_VENTILATED && invoice.getCompany().getAccountConfig().getAllowCancelVentilatedInvoice())  {
			cancelMove();
		}
		
		setStatus();
		
	}
	
	protected void setStatus(){
		
		invoice.setStatusSelect(STATUS_CANCELED);
		
	}
	
	protected void cancelMove() throws AxelorException{
		
		if(invoice.getMove() == null)   {  return;  }
			
		if(invoice.getInTaxTotalRemaining().compareTo(invoice.getInTaxTotal()) != 0)  {
			
			throw new AxelorException(String.format("%s :\n Move should be unReconcile before to cancel the invoice",
					GeneralServiceAccount.getExceptionAccountingMsg()), IException.CONFIGURATION_ERROR);
		}
		
		if(invoice.getOldMove() != null)  {
			
			throw new AxelorException(String.format("%s :\n Invoice is passed in doubfult debit, and can't be canceled",
					GeneralServiceAccount.getExceptionAccountingMsg()), IException.CONFIGURATION_ERROR);
		}
		
		try{
			
			Move move = invoice.getMove();
			
			invoice.setMove(null);
			invoice.setInTaxTotalRemaining(BigDecimal.ZERO);

			if(invoice.getCompany().getAccountConfig().getAllowRemovalValidatedMove())  {
				Beans.get(MoveRepository.class).remove(move);
			}
			else  {
				move.setStatusSelect(MoveRepository.STATUS_CANCELED);
			}
			
		}
		catch(Exception e)  {
			
			throw new AxelorException(String.format("%s :\n Too many accounting operations are used on this invoice, so invoice can't be canceled",
					GeneralServiceAccount.getExceptionAccountingMsg()), IException.CONFIGURATION_ERROR);
			
		}
		
		
	}
	
}
@@ -970,44 +970,133 @@
 ice.
-administration.GeneralServiceAccount
+invoice.workflow.WorkflowInvoice;%0Aimport com.axelor.apps.base.db.Period;%0Aimport com.axelor.apps.base.db.repo.PeriodRepository
 ;%0Aim
@@ -1108,39 +1108,36 @@
 com.axelor.apps.
-account
+base
 .service.invoice
@@ -1133,37 +1133,18 @@
 ice.
-invoice.workflow.WorkflowInvo
+PeriodServ
 ice;
@@ -1756,27 +1756,36 @@
 ption%7B%0A%09%09%0A%09%09
-if(
+Move move = 
 invoice.getM
@@ -1789,16 +1789,30 @@
 etMove()
+;%0A%09%09%0A%09%09if(move
  == null
@@ -1963,23 +1963,16 @@
 format(%22
-%25s :%5Cn 
 Move sho
@@ -1980,17 +1980,17 @@
 ld be un
-R
+r
 econcile
@@ -2023,64 +2023,8 @@
 ice%22
-,%0A%09%09%09%09%09GeneralServiceAccount.getExceptionAccountingMsg()
 ), I
@@ -2148,23 +2148,16 @@
 format(%22
-%25s :%5Cn 
 Invoice 
@@ -2211,64 +2211,340 @@
 led%22
-,%0A%09%09%09%09%09GeneralServiceAccount.getExceptionAccountingMsg()
+), IException.CONFIGURATION_ERROR);%0A%09%09%7D%0A%09%09%0A%09%09Period period = Beans.get(PeriodService.class).getPeriod(move.getDate(), move.getCompany());%0A%09%09if(period == null %7C%7C period.getStatusSelect() == PeriodRepository.STATUS_CLOSED)  %7B%0A%09%09%09throw new AxelorException(String.format(%22Invoice is ventilated on a closed period, and can't be canceled%22
 ), I
@@ -2597,46 +2597,8 @@
 %09%09%09%0A
-%09%09%09Move move = invoice.getMove();%0A%09%09%09%0A
 %09%09%09i
@@ -2966,16 +2966,8 @@
 at(%22
-%25s :%5Cn T
 oo m
@@ -3051,64 +3051,8 @@
 led%22
-,%0A%09%09%09%09%09GeneralServiceAccount.getExceptionAccountingMsg()
 ), I

Add a control on period status to authorize cancelation of a ventilated invoice