First commit waiting for Budget Alert
This commit is contained in:
@ -0,0 +1,17 @@
|
||||
apply plugin: "com.axelor.app-module"
|
||||
|
||||
apply from: "../version.gradle"
|
||||
|
||||
apply {
|
||||
version = openSuiteVersion
|
||||
}
|
||||
|
||||
axelor {
|
||||
title "Axelor Business Project"
|
||||
description "Axelor Business Project Module"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":modules:axelor-human-resource")
|
||||
compile project(":modules:axelor-contract")
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.db.repo;
|
||||
|
||||
import com.axelor.apps.base.db.AppBusinessProject;
|
||||
import com.axelor.apps.base.db.repo.AppBusinessProjectRepository;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Inject;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
public class AppBusinessProjectManagementRepository extends AppBusinessProjectRepository {
|
||||
|
||||
@Inject private TeamTaskRepository teamTaskRepo;
|
||||
|
||||
@Override
|
||||
public AppBusinessProject save(AppBusinessProject entity) {
|
||||
try {
|
||||
if (!Strings.isNullOrEmpty(entity.getExculdeTaskInvoicing())) {
|
||||
teamTaskRepo.all().filter(entity.getExculdeTaskInvoicing()).count();
|
||||
}
|
||||
return super.save(entity);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
throw new PersistenceException(I18n.get(IExceptionMessage.INVALID_EXCLUDE_TASK_FILTER));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.db.repo;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.repo.InvoiceManagementRepository;
|
||||
import com.axelor.inject.Beans;
|
||||
|
||||
public class InvoiceProjectRepository extends InvoiceManagementRepository {
|
||||
|
||||
@Override
|
||||
public void remove(Invoice entity) {
|
||||
|
||||
Beans.get(InvoicingProjectRepository.class)
|
||||
.all()
|
||||
.filter("self.invoice.id = ?", entity.getId())
|
||||
.remove();
|
||||
|
||||
super.remove(entity);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.db.repo;
|
||||
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.i18n.I18n;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
public class InvoicingProjectManagementRepository extends InvoicingProjectRepository {
|
||||
|
||||
@Override
|
||||
public void remove(InvoicingProject entity) {
|
||||
|
||||
if (entity.getInvoice() != null) {
|
||||
throw new PersistenceException(
|
||||
I18n.get(
|
||||
"Since the invoice has already been generated, it's impossible to delete this record"));
|
||||
} else {
|
||||
super.remove(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.db.repo;
|
||||
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.supplychain.db.repo.SaleOrderSupplychainRepository;
|
||||
|
||||
public class SaleOrderProjectRepository extends SaleOrderSupplychainRepository {
|
||||
@Override
|
||||
public SaleOrder copy(SaleOrder entity, boolean deep) {
|
||||
|
||||
SaleOrder copy = super.copy(entity, deep);
|
||||
|
||||
copy.setProject(null);
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.db.repo;
|
||||
|
||||
import com.axelor.apps.hr.db.repo.TeamTaskHRRepository;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
|
||||
public class TeamTaskBusinessProjectRepository extends TeamTaskHRRepository {
|
||||
|
||||
@Override
|
||||
public TeamTask copy(TeamTask entity, boolean deep) {
|
||||
entity.setSaleOrderLine(null);
|
||||
entity.setInvoiceLine(null);
|
||||
return super.copy(entity, deep);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.exception;
|
||||
|
||||
/**
|
||||
* Interface of Exceptions. Enum all exception of axelor-account.
|
||||
*
|
||||
* @author dubaux
|
||||
*/
|
||||
public interface IExceptionMessage {
|
||||
|
||||
static final String FOLDER_TEMPLATE = /*$$(*/ "You must add a sale order template" /*)*/;
|
||||
static final String INVOICING_PROJECT_EMPTY = /*$$(*/
|
||||
"You haven't select any element to invoice" /*)*/;
|
||||
static final String INVOICING_PROJECT_PROJECT = /*$$(*/ "You must select a project/task" /*)*/;
|
||||
static final String INVOICING_PROJECT_PROJECT_PARTNER = /*$$(*/
|
||||
"There is no customer for this project/task" /*)*/;
|
||||
static final String INVOICING_PROJECT_PROJECT_PRODUCT = /*$$(*/
|
||||
"You haven't select a product to invoice for the task %s" /*)*/;
|
||||
static final String INVOICING_PROJECT_PROJECT_COMPANY = /*$$(*/
|
||||
"You haven't select a company on the main project" /*)*/;
|
||||
static final String SALE_ORDER_NO_PROJECT = /*$$(*/ "No Project selected" /*)*/;
|
||||
static final String SALE_ORDER_NO_LINES = /*$$(*/ "No Line can be used for tasks" /*)*/;
|
||||
static final String SALE_ORDER_NO_TYPE_GEN_PROJECT = /*$$(*/
|
||||
"No type of generation project has been selected" /*)*/;
|
||||
static final String SALE_ORDER_BUSINESS_PROJECT = /*$$(*/
|
||||
"The project is configured to be alone" /*)*/;
|
||||
static final String JOB_COSTING_APP = /*$$(*/ "Job costing" /*)*/;
|
||||
String FACTORY_NO_FOUND = /*$$(*/ "Factory not found this type of generator" /*)*/;
|
||||
String FACTORY_FILL_WITH_PROJECT_ALONE = /*$$(*/
|
||||
"You can't fill a project with the strategy Project Alone." /*)*/;
|
||||
|
||||
static final String NO_PROJECT_IN_CONTEXT = /*$$(*/ "No project found in context" /*)*/;
|
||||
static final String LINES_NOT_SELECTED = /*$$(*/ "Please select lines" /*)*/;
|
||||
|
||||
static final String SALE_ORDER_GENERATE_FILL_PROJECT_ERROR_1 = /*$$(*/
|
||||
"Products must be Service type and Method of Supply Produce." /*)*/;
|
||||
static final String SALE_ORDER_GENERATE_FILL_PROJECT_ERROR_2 = /*$$(*/
|
||||
"Please complete the order lines with at least one product type 'Service' and the supply mode 'Produce'" /*)*/;
|
||||
|
||||
static final String INVALID_EXCLUDE_TASK_FILTER = /*$$(*/
|
||||
"Invalid exclude task for invoicing filter" /*)*/;
|
||||
|
||||
static final String BATCH_TASK_UPDATION_1 = /*$$(*/ "Task %s" /*)*/;
|
||||
|
||||
static final String BATCH_TASK_UPDATION_2 = /*$$(*/ "Tasks updation completed : " /*)*/;
|
||||
|
||||
static final String BATCH_INVOICING_PROJECT_1 = /*$$(*/ "Project %s" /*)*/;
|
||||
|
||||
static final String BATCH_INVOICING_PROJECT_2 = /*$$(*/ "Generated invoicing project" /*)*/;
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.mobile;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.auth.AuthUtils;
|
||||
import com.axelor.auth.db.User;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BusinessProjectMobileController {
|
||||
|
||||
/*
|
||||
* This method is used in mobile application.
|
||||
* It was in ProjectTaskBusinessServiceImpl
|
||||
* @param request
|
||||
* @param response
|
||||
*
|
||||
* POST /open-suite-webapp/ws/action/com.axelor.apps.businessproject.mobile.BusinessProjectMobileController:getProjects
|
||||
* Content-Type: application/json
|
||||
*
|
||||
* URL: com.axelor.apps.businessproject.mobile.BusinessProjectMobileController:getProjects
|
||||
* fields: no field
|
||||
*
|
||||
* payload:
|
||||
* { "data": {
|
||||
* "action": "com.axelor.apps.businessproject.mobile.BusinessProjectMobileController:getProjects"
|
||||
* } }
|
||||
*/
|
||||
public void getProjects(ActionRequest request, ActionResponse response) {
|
||||
|
||||
List<Map<String, String>> dataList = new ArrayList<Map<String, String>>();
|
||||
try {
|
||||
User user = AuthUtils.getUser();
|
||||
if (user != null) {
|
||||
List<Project> projectList =
|
||||
Beans.get(ProjectRepository.class).all().filter("self.imputable = true").fetch();
|
||||
for (Project project : projectList) {
|
||||
if ((project.getMembersUserSet() != null && project.getMembersUserSet().contains(user))
|
||||
|| user.equals(project.getAssignedTo())) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("name", project.getName());
|
||||
map.put("id", project.getId().toString());
|
||||
dataList.add(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
response.setData(dataList);
|
||||
response.setTotal(dataList.size());
|
||||
} catch (Exception e) {
|
||||
response.setStatus(-1);
|
||||
response.setError(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.module;
|
||||
|
||||
import com.axelor.app.AxelorModule;
|
||||
import com.axelor.apps.account.db.repo.InvoiceManagementRepository;
|
||||
import com.axelor.apps.bankpayment.service.invoice.payment.InvoicePaymentValidateServiceBankPayImpl;
|
||||
import com.axelor.apps.base.db.repo.AppBusinessProjectRepository;
|
||||
import com.axelor.apps.businessproject.db.repo.AppBusinessProjectManagementRepository;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoiceProjectRepository;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectManagementRepository;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectRepository;
|
||||
import com.axelor.apps.businessproject.db.repo.SaleOrderProjectRepository;
|
||||
import com.axelor.apps.businessproject.db.repo.TeamTaskBusinessProjectRepository;
|
||||
import com.axelor.apps.businessproject.service.ContractLineServiceProjectImpl;
|
||||
import com.axelor.apps.businessproject.service.ExpenseLineProjectService;
|
||||
import com.axelor.apps.businessproject.service.ExpenseLineProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.ExpenseServiceProjectImpl;
|
||||
import com.axelor.apps.businessproject.service.InvoiceLineProjectService;
|
||||
import com.axelor.apps.businessproject.service.InvoiceLineProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.InvoicePaymentValidateProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.InvoiceServiceProjectImpl;
|
||||
import com.axelor.apps.businessproject.service.ProductTaskTemplateService;
|
||||
import com.axelor.apps.businessproject.service.ProductTaskTemplateServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.ProjectBusinessService;
|
||||
import com.axelor.apps.businessproject.service.ProjectBusinessServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.ProjectContractServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.ProjectFolderService;
|
||||
import com.axelor.apps.businessproject.service.ProjectFolderServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.ProjectPurchaseServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.ProjectStockMoveInvoiceServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.PurchaseOrderInvoiceProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.PurchaseOrderLineProjectService;
|
||||
import com.axelor.apps.businessproject.service.PurchaseOrderLineServiceProjectImpl;
|
||||
import com.axelor.apps.businessproject.service.SaleOrderInvoiceProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.SaleOrderLineProjectService;
|
||||
import com.axelor.apps.businessproject.service.SaleOrderLineProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.TeamTaskBusinessProjectService;
|
||||
import com.axelor.apps.businessproject.service.TeamTaskBusinessProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.TimesheetLineBusinessService;
|
||||
import com.axelor.apps.businessproject.service.TimesheetLineProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.TimesheetProjectService;
|
||||
import com.axelor.apps.businessproject.service.TimesheetProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.WorkflowCancelServiceProjectImpl;
|
||||
import com.axelor.apps.businessproject.service.WorkflowValidationServiceProjectImpl;
|
||||
import com.axelor.apps.businessproject.service.WorkflowVentilationProjectServiceImpl;
|
||||
import com.axelor.apps.businessproject.service.app.AppBusinessProjectService;
|
||||
import com.axelor.apps.businessproject.service.app.AppBusinessProjectServiceImpl;
|
||||
import com.axelor.apps.contract.service.ContractLineServiceImpl;
|
||||
import com.axelor.apps.contract.service.ContractServiceImpl;
|
||||
import com.axelor.apps.hr.db.repo.TeamTaskHRRepository;
|
||||
import com.axelor.apps.hr.service.expense.ExpenseServiceImpl;
|
||||
import com.axelor.apps.hr.service.timesheet.TimesheetLineServiceImpl;
|
||||
import com.axelor.apps.hr.service.timesheet.TimesheetServiceImpl;
|
||||
import com.axelor.apps.project.service.ProjectServiceImpl;
|
||||
import com.axelor.apps.project.service.TeamTaskProjectServiceImpl;
|
||||
import com.axelor.apps.supplychain.db.repo.SaleOrderSupplychainRepository;
|
||||
import com.axelor.apps.supplychain.service.InvoiceLineSupplychainService;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderInvoiceServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderLineServiceSupplychainImpl;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderInvoiceServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderLineServiceSupplyChainImpl;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderPurchaseServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.StockMoveInvoiceServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.invoice.InvoiceServiceSupplychainImpl;
|
||||
import com.axelor.apps.supplychain.service.workflow.WorkflowCancelServiceSupplychainImpl;
|
||||
import com.axelor.apps.supplychain.service.workflow.WorkflowValidationServiceSupplychainImpl;
|
||||
import com.axelor.apps.supplychain.service.workflow.WorkflowVentilationServiceSupplychainImpl;
|
||||
|
||||
public class BusinessProjectModule extends AxelorModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(SaleOrderInvoiceServiceImpl.class).to(SaleOrderInvoiceProjectServiceImpl.class);
|
||||
bind(PurchaseOrderInvoiceServiceImpl.class).to(PurchaseOrderInvoiceProjectServiceImpl.class);
|
||||
bind(TimesheetServiceImpl.class).to(TimesheetProjectServiceImpl.class);
|
||||
bind(TimesheetProjectService.class).to(TimesheetProjectServiceImpl.class);
|
||||
bind(TimesheetLineServiceImpl.class).to(TimesheetLineProjectServiceImpl.class);
|
||||
bind(ExpenseServiceImpl.class).to(ExpenseServiceProjectImpl.class);
|
||||
bind(ProjectServiceImpl.class).to(ProjectBusinessServiceImpl.class);
|
||||
bind(ProjectBusinessService.class).to(ProjectBusinessServiceImpl.class);
|
||||
bind(InvoicingProjectRepository.class).to(InvoicingProjectManagementRepository.class);
|
||||
bind(AppBusinessProjectService.class).to(AppBusinessProjectServiceImpl.class);
|
||||
bind(InvoiceServiceSupplychainImpl.class).to(InvoiceServiceProjectImpl.class);
|
||||
bind(TeamTaskProjectServiceImpl.class).to(TeamTaskBusinessProjectServiceImpl.class);
|
||||
bind(TeamTaskBusinessProjectService.class).to(TeamTaskBusinessProjectServiceImpl.class);
|
||||
bind(SaleOrderSupplychainRepository.class).to(SaleOrderProjectRepository.class);
|
||||
bind(ProductTaskTemplateService.class).to(ProductTaskTemplateServiceImpl.class);
|
||||
bind(StockMoveInvoiceServiceImpl.class).to(ProjectStockMoveInvoiceServiceImpl.class);
|
||||
bind(SaleOrderPurchaseServiceImpl.class).to(ProjectPurchaseServiceImpl.class);
|
||||
bind(PurchaseOrderLineServiceSupplychainImpl.class)
|
||||
.to(PurchaseOrderLineServiceProjectImpl.class);
|
||||
bind(SaleOrderLineProjectService.class).to(SaleOrderLineProjectServiceImpl.class);
|
||||
bind(PurchaseOrderLineProjectService.class).to(PurchaseOrderLineServiceProjectImpl.class);
|
||||
bind(ExpenseLineProjectService.class).to(ExpenseLineProjectServiceImpl.class);
|
||||
bind(InvoiceLineProjectService.class).to(InvoiceLineProjectServiceImpl.class);
|
||||
bind(InvoiceManagementRepository.class).to(InvoiceProjectRepository.class);
|
||||
bind(WorkflowVentilationServiceSupplychainImpl.class)
|
||||
.to(WorkflowVentilationProjectServiceImpl.class);
|
||||
bind(TimesheetLineBusinessService.class).to(TimesheetLineProjectServiceImpl.class);
|
||||
bind(WorkflowValidationServiceSupplychainImpl.class)
|
||||
.to(WorkflowValidationServiceProjectImpl.class);
|
||||
bind(WorkflowCancelServiceSupplychainImpl.class).to(WorkflowCancelServiceProjectImpl.class);
|
||||
bind(TeamTaskHRRepository.class).to(TeamTaskBusinessProjectRepository.class);
|
||||
bind(SaleOrderLineServiceSupplyChainImpl.class).to(SaleOrderLineProjectServiceImpl.class);
|
||||
bind(InvoiceLineSupplychainService.class).to(InvoiceLineProjectServiceImpl.class);
|
||||
bind(ContractServiceImpl.class).to(ProjectContractServiceImpl.class);
|
||||
bind(ContractLineServiceImpl.class).to(ContractLineServiceProjectImpl.class);
|
||||
bind(AppBusinessProjectRepository.class).to(AppBusinessProjectManagementRepository.class);
|
||||
bind(InvoicePaymentValidateServiceBankPayImpl.class)
|
||||
.to(InvoicePaymentValidateProjectServiceImpl.class);
|
||||
bind(ProjectFolderService.class).to(ProjectFolderServiceImpl.class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.report;
|
||||
|
||||
public interface IReport {
|
||||
|
||||
public static final String PROJECT = "Project.rptdesign";
|
||||
public static final String INVOICE_ANNEX = "InvoiceAnnex.rptdesign";
|
||||
public static final String PLANNIF_AND_COST = "PlannificationAndCost.rptdesign";
|
||||
public static final String INVOICING_PROJECT_ANNEX = "InvoicingProjectAnnex.rptdesign";
|
||||
}
|
||||
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.report;
|
||||
|
||||
public interface ITranslation {
|
||||
|
||||
public static final String PROJECT_TITLE = /*$$(*/ "Project.title"; /*)*/
|
||||
public static final String PROJECT_CUSTOMER = /*$$(*/ "Project.customer"; /*)*/
|
||||
public static final String PROJECT_CURRENCY = /*$$(*/ "Project.currency"; /*)*/
|
||||
public static final String PROJECT_INITIAL = /*$$(*/ "Project.initial"; /*)*/
|
||||
public static final String PROJECT_SO = /*$$(*/ "Project.salesOrders"; /*)*/
|
||||
public static final String PROJECT_TASK = /*$$(*/ "Project.tasks"; /*)*/
|
||||
public static final String PROJECT_TASK_NAME = /*$$(*/ "Project.taskName"; /*)*/
|
||||
public static final String PROJECT_END_DATE = /*$$(*/ "Project.endDate"; /*)*/
|
||||
public static final String PROJECT_PROGRESS = /*$$(*/ "Project.progress"; /*)*/
|
||||
public static final String PROJECT_SO_NO = /*$$(*/ "Project.salesOrderNumber"; /*)*/
|
||||
public static final String PROJECT_PO_NO = /*$$(*/ "Project.purchaseOrderNumber"; /*)*/
|
||||
public static final String PROJECT_DATE = /*$$(*/ "Project.date"; /*)*/
|
||||
public static final String PROJECT_SALES = /*$$(*/ "Project.sales"; /*)*/
|
||||
public static final String PROJECT_COSTS = /*$$(*/ "Project.costs"; /*)*/
|
||||
public static final String PROJECT_Margin = /*$$(*/ "Project.margin"; /*)*/
|
||||
public static final String PROJECT_EXPECTED_MARGIN = /*$$(*/ "Project.expectedMargin"; /*)*/
|
||||
public static final String PROJECT_EXPECTED_REVENUE = /*$$(*/ "Project.expectedRevenue"; /*)*/
|
||||
public static final String PROJECT_EXPECTED_COSTS = /*$$(*/ "Project.expectedCosts"; /*)*/
|
||||
public static final String PROJECT_TOTAL_SALES = /*$$(*/ "Project.totalSales"; /*)*/
|
||||
public static final String PROJECT_TOTAL_TURNOVER = /*$$(*/ "Project.totalTurnover"; /*)*/
|
||||
public static final String PROJECT_TOTAL_COSTS = /*$$(*/ "Project.totalCosts"; /*)*/
|
||||
public static final String PROJECT_TOTAL_MARGIN = /*$$(*/ "Project.totalMargin"; /*)*/
|
||||
public static final String PROJECT_INVOICED = /*$$(*/ "Project.invoiced"; /*)*/
|
||||
public static final String PROJECT_TURNOVER = /*$$(*/ "Project.turnover"; /*)*/
|
||||
public static final String PROJECT_SALES_INVOICE = /*$$(*/ "Project.salesInvoice"; /*)*/
|
||||
public static final String PROJECT_INVOICE_NUMBER = /*$$(*/ "Project.invoiceNumber"; /*)*/
|
||||
public static final String PROJECT_SUB_TYPE = /*$$(*/ "Project.subType"; /*)*/
|
||||
public static final String PROJECT_AMOUNT = /*$$(*/ "Project.amount"; /*)*/
|
||||
public static final String PROJECT_PURCHASE = /*$$(*/ "Project.purchase"; /*)*/
|
||||
public static final String PROJECT_EXPENSE = /*$$(*/ "Project.expense"; /*)*/
|
||||
public static final String PROJECT_EMPLOYEE = /*$$(*/ "Project.employee"; /*)*/
|
||||
public static final String PROJECT_PLANNING = /*$$(*/ "Project.planning"; /*)*/
|
||||
public static final String PROJECT_TIMESHEET = /*$$(*/ "Project.timesheet"; /*)*/
|
||||
public static final String PROJECT_TOTAL_HOURS = /*$$(*/ "Project.totalHours"; /*)*/
|
||||
public static final String PROJECT_HOURLY_RATE = /*$$(*/ "Project.hourlyRate"; /*)*/
|
||||
public static final String PROJECT_ANALYTICAL = /*$$(*/ "Project.analyticalLines"; /*)*/
|
||||
public static final String PROJECT_ANALYTICAL_AXIS = /*$$(*/ "Project.analyticalAxis"; /*)*/
|
||||
public static final String PROJECT_ANALYTICAL_ACCOUNT = /*$$(*/ "Project.analyticalAccount"; /*)*/
|
||||
public static final String PROJECT_TYPE = /*$$(*/ "Project.type"; /*)*/
|
||||
public static final String PROJECT_TOTAL = /*$$(*/ "Project.total"; /*)*/
|
||||
public static final String PROJECT_RESULT = /*$$(*/ "Project.result"; /*)*/
|
||||
public static final String PROJECT_CHART_TITLE = /*$$(*/ "Project.turnoverAndCostPerMonth"; /*)*/
|
||||
public static final String PROJECT_MANUAL_ELEMENT = /*$$(*/ "Project.manualElement"; /*)*/
|
||||
public static final String PROJECT_MANUAL_ELEMENT_TITLE = /*$$(*/
|
||||
"Project.manualElementTitle"; /*)*/
|
||||
public static final String PROJECT_REPORT_TITLE_FOR_PLANIFICATION_AND_COST = /*$$(*/
|
||||
"Project planification and costs"; /*)*/
|
||||
public static final String PROJECT_REPORT_TITLE_FOR_FINANCIAL = /*$$(*/
|
||||
"Projects financial report"; /*)*/
|
||||
|
||||
public static final String INVOICE_PURCHASE_INVOICE_NO_ANNEX = /*$$(*/
|
||||
"Invoice.purchaseInvoiceNoAnnex"; /*)*/
|
||||
public static final String INVOICE_PURCHASE_REFUND_NO_ANNEX = /*$$(*/
|
||||
"Invoice.purchaseRefundNoAnnex"; /*)*/
|
||||
public static final String INVOICE_INVOICE_NO_ANNEX = /*$$(*/ "Invoice.invoiceNoAnnex"; /*)*/
|
||||
public static final String INVOICE_DRAFT_INVOICE_NO_ANNEX = /*$$(*/
|
||||
"Invoice.draftInvoiceNoAnnex"; /*)*/
|
||||
public static final String INVOICE_REFUND_NO_ANNEX = /*$$(*/ "Invoice.refundNoAnnex"; /*)*/
|
||||
|
||||
public static final String INVOICE_TIMESHEET_TITLE = /*$$(*/ "Invoice.timesheetTitle"; /*)*/
|
||||
public static final String INVOICE_EXPENSE_TITLE = /*$$(*/ "Invoice.expenseTitle"; /*)*/
|
||||
|
||||
public static final String INVOICE_TIMESHEET_USER = /*$$(*/ "Invoice.timesheetUser"; /*)*/
|
||||
public static final String INVOICE_TIMESHEET_ACTIVITY = /*$$(*/ "Invoice.timesheetActivity"; /*)*/
|
||||
public static final String INVOICE_TIMESHEET_DURATION = /*$$(*/ "Invoice.timesheetDuration"; /*)*/
|
||||
public static final String INVOICE_SUPPLIER_REFERENCE = /*$$(*/ "Invoice.supplierReference"; /*)*/
|
||||
|
||||
public static final String INVOICE_EXPENSE_TOTAL_AMOUNT = /*$$(*/
|
||||
"Invoice.expenseTotalAmount"; /*)*/
|
||||
public static final String INVOICE_EXPENSE_TAX_AMOUNT = /*$$(*/ "Invoice.expenseTaxAmount"; /*)*/
|
||||
public static final String INVOICE_EXPENSE_PRODUCT = /*$$(*/ "Invoice.expenseProduct"; /*)*/
|
||||
|
||||
public static final String PROJECT_CONSUMED_TIME = /*$$(*/ "Project.consumedTime"; /*)*/
|
||||
public static final String PROJECT_TOTAL_TIME_CHART = /*$$(*/ "Project.totalTimeChart"; /*)*/
|
||||
public static final String PROJECT_TOTAL_COST_CHART = /*$$(*/ "Project.totalCostChart"; /*)*/
|
||||
public static final String PROJECT_PLANNED_TIME = /*$$(*/ "Project.plannedTime"; /*)*/
|
||||
public static final String PROJECT_SYNTHESIS = /*$$(*/ "Project.synthesis"; /*)*/
|
||||
public static final String PROJECT_TIME = /*$$(*/ "Project.time"; /*)*/
|
||||
public static final String PROJECT_REAL_PASSED = /*$$(*/ "Project.realPassed"; /*)*/
|
||||
public static final String PROJECT_PLANNED_PASSED = /*$$(*/ "Project.plannedPast"; /*)*/
|
||||
public static final String PROJECT_REMAIN_PLANNED = /*$$(*/ "Project.remainPlanned"; /*)*/
|
||||
public static final String PROJECT_REMAIN_THEORY = /*$$(*/ "Project.remainInTheory"; /*)*/
|
||||
public static final String PROJECT_CHART_MONTH_PASSED_TIME = /*$$(*/
|
||||
"Project.chartTimePassedPerMonth"; /*)*/
|
||||
public static final String PROJECT_CHART_MONTH_PASSED_COST = /*$$(*/
|
||||
"Project.chartCostPassedPerMonth"; /*)*/
|
||||
public static final String PROJECT_CHART_MONTH_REMAINING_TIME = /*$$(*/
|
||||
"Project.chartTimeRemainingPerMonth"; /*)*/
|
||||
public static final String PROJECT_CHART_MONTH_REMAINING_COST = /*$$(*/
|
||||
"Project.chartCostRemainingPerMonth"; /*)*/
|
||||
|
||||
// InvoicingProject
|
||||
public static final String INVOICING_PROJECT_ANNEX_DEADLINE = /*$$(*/
|
||||
"InvoicingProjectAnnex.deadline"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_INVOICE_GENERATED = /*$$(*/
|
||||
"InvoicingProjectAnnex.invoiceGenerated"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_BUSINESS_PROJECT = /*$$(*/
|
||||
"InvoicingProjectAnnex.businessProject"; /*)*/
|
||||
// Titles
|
||||
public static final String INVOICING_PROJECT_ANNEX_TITLE = /*$$(*/
|
||||
"InvoicingProjectAnnex.annex"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TITLE_SALES = /*$$(*/
|
||||
"InvoicingProjectAnnex.sales"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TITLE_PURCHASES = /*$$(*/
|
||||
"InvoicingProjectAnnex.purchases"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TITLE_TIME_SPENT = /*$$(*/
|
||||
"InvoicingProjectAnnex.timeSpent"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TITLE_EXPENSES = /*$$(*/
|
||||
"InvoicingProjectAnnex.expenses"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TITLE_PROJECTS = /*$$(*/
|
||||
"InvoicingProjectAnnex.projects"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TITLE_TASKS = /*$$(*/
|
||||
"InvoicingProjectAnnex.tasks"; /*)*/
|
||||
// InvoicingProject - Sales
|
||||
public static final String INVOICING_PROJECT_ANNEX_CODE = /*$$(*/
|
||||
"InvoicingProjectAnnex.code"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_PRODUCT_NAME = /*$$(*/
|
||||
"InvoicingProjectAnnex.productName"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_UNIT = /*$$(*/
|
||||
"InvoicingProjectAnnex.unit"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_QTY = /*$$(*/
|
||||
"InvoicingProjectAnnex.qty"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_UNIT_PRICE_WT = /*$$(*/
|
||||
"InvoicingProjectAnnex.unitPriceWT"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_UNIT_PRICE_ATI = /*$$(*/
|
||||
"InvoicingProjectAnnex.unitPriceATI"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TOTAL_ATI = /*$$(*/
|
||||
"InvoicingProjectAnnex.totalATI"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TOTAL_WT = /*$$(*/
|
||||
"InvoicingProjectAnnex.totalWT"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_ESTIMATED_SHIPPING_DATE = /*$$(*/
|
||||
"InvoicingProjectAnnex.estimatedShippingDate"; /*)*/
|
||||
// InvoicingProject - Purchases
|
||||
public static final String INVOICING_PROJECT_ANNEX_PURCHASE_ORDER = /*$$(*/
|
||||
"InvoicingProjectAnnex.purchaseOrder"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_SUPPLIER = /*$$(*/
|
||||
"InvoicingProjectAnnex.supplier"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TO_INVOICE = /*$$(*/
|
||||
"InvoicingProjectAnnex.toInvoice"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_INVOICED = /*$$(*/
|
||||
"InvoicingProjectAnnex.invoiced"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_CURRENCY = /*$$(*/
|
||||
"InvoicingProjectAnnex.currency"; /*)*/
|
||||
// InvoicingProject - TimeSpent
|
||||
public static final String INVOICING_PROJECT_ANNEX_USER = /*$$(*/
|
||||
"InvoicingProjectAnnex.user"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TASK = /*$$(*/
|
||||
"InvoicingProjectAnnex.task"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_DATE = /*$$(*/
|
||||
"InvoicingProjectAnnex.date"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_ACTIVITY = /*$$(*/
|
||||
"InvoicingProjectAnnex.activity"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_DURATION = /*$$(*/
|
||||
"InvoicingProjectAnnex.duration"; /*)*/
|
||||
// InvoicingProject - Expenses
|
||||
public static final String INVOICING_PROJECT_ANNEX_PROJECT = /*$$(*/
|
||||
"InvoicingProjectAnnex.project"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_EXPENSE_TYPE = /*$$(*/
|
||||
"InvoicingProjectAnnex.expenseType"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_EXPENSE_DATE = /*$$(*/
|
||||
"InvoicingProjectAnnex.expenseDate"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TOTAL_TAX = /*$$(*/
|
||||
"InvoicingProjectAnnex.totalTax"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_COMMENTS = /*$$(*/
|
||||
"InvoicingProjectAnnex.comments"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TOTAL_AMOUNT_WITH_TAX = /*$$(*/
|
||||
"InvoicingProjectAnnex.totalAmountWT"; /*)*/
|
||||
// InvoicingProject - Project
|
||||
public static final String INVOICING_PROJECT_ANNEX_NAME = /*$$(*/
|
||||
"InvoicingProjectAnnex.name"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_PARENT_PROJECT = /*$$(*/
|
||||
"InvoicingProjectAnnex.parentProject"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_CUSTOMER = /*$$(*/
|
||||
"InvoicingProjectAnnex.customer"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_ASSIGNED_TO = /*$$(*/
|
||||
"InvoicingProjectAnnex.assignedTo"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_FROM_DATE = /*$$(*/
|
||||
"InvoicingProjectAnnex.fromDate"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_TO_DATE = /*$$(*/
|
||||
"InvoicingProjectAnnex.toDate"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_DUE_DATE = /*$$(*/
|
||||
"InvoicingProjectAnnex.dueDate"; /*)*/
|
||||
// InvoicingProject - Tasks
|
||||
public static final String INVOICING_PROJECT_ANNEX_TASK_DATE = /*$$(*/
|
||||
"InvoicingProjectAnnex.taskDate"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_STATUS = /*$$(*/
|
||||
"InvoicingProjectAnnex.status"; /*)*/
|
||||
public static final String INVOICING_PROJECT_ANNEX_PROGRESS = /*$$(*/
|
||||
"InvoicingProjectAnnex.progress"; /*)*/
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.AnalyticMoveLine;
|
||||
import com.axelor.apps.base.service.CurrencyService;
|
||||
import com.axelor.apps.base.service.app.AppBaseService;
|
||||
import com.axelor.apps.base.service.tax.AccountManagementService;
|
||||
import com.axelor.apps.contract.db.Contract;
|
||||
import com.axelor.apps.contract.db.ContractLine;
|
||||
import com.axelor.apps.contract.service.ContractLineServiceImpl;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class ContractLineServiceProjectImpl extends ContractLineServiceImpl {
|
||||
|
||||
@Inject
|
||||
public ContractLineServiceProjectImpl(
|
||||
AppBaseService appBaseService,
|
||||
AccountManagementService accountManagementService,
|
||||
CurrencyService currencyService) {
|
||||
super(appBaseService, accountManagementService, currencyService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContractLine createAnalyticDistributionWithTemplate(
|
||||
ContractLine contractLine, Contract contract) {
|
||||
contractLine = super.createAnalyticDistributionWithTemplate(contractLine, contract);
|
||||
|
||||
Project project = contract.getProject();
|
||||
|
||||
if (project != null) {
|
||||
List<AnalyticMoveLine> analyticMoveLineList = contractLine.getAnalyticMoveLineList();
|
||||
|
||||
analyticMoveLineList.forEach(analyticMoveLine -> analyticMoveLine.setProject(project));
|
||||
contractLine.setAnalyticMoveLineList(analyticMoveLineList);
|
||||
}
|
||||
return contractLine;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import java.util.List;
|
||||
|
||||
public interface ExpenseLineProjectService {
|
||||
|
||||
public void setProject(List<Long> expenseLineIds, Project project);
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.hr.db.ExpenseLine;
|
||||
import com.axelor.apps.hr.db.repo.ExpenseLineRepository;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
|
||||
public class ExpenseLineProjectServiceImpl implements ExpenseLineProjectService {
|
||||
|
||||
@Inject private ExpenseLineRepository expenseLineRepo;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void setProject(List<Long> expenseLineIds, Project project) {
|
||||
|
||||
if (expenseLineIds != null) {
|
||||
|
||||
List<ExpenseLine> expenseLineList =
|
||||
expenseLineRepo.all().filter("self.id in ?1", expenseLineIds).fetch();
|
||||
|
||||
for (ExpenseLine line : expenseLineList) {
|
||||
line.setProject(project);
|
||||
expenseLineRepo.save(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.service.AccountManagementAccountService;
|
||||
import com.axelor.apps.account.service.AccountingSituationService;
|
||||
import com.axelor.apps.account.service.AnalyticMoveLineService;
|
||||
import com.axelor.apps.account.service.app.AppAccountService;
|
||||
import com.axelor.apps.account.service.move.MoveLineService;
|
||||
import com.axelor.apps.account.service.move.MoveService;
|
||||
import com.axelor.apps.account.service.payment.PaymentModeService;
|
||||
import com.axelor.apps.hr.db.ExpenseLine;
|
||||
import com.axelor.apps.hr.db.repo.ExpenseRepository;
|
||||
import com.axelor.apps.hr.service.config.AccountConfigHRService;
|
||||
import com.axelor.apps.hr.service.config.HRConfigService;
|
||||
import com.axelor.apps.hr.service.expense.ExpenseServiceImpl;
|
||||
import com.axelor.apps.message.service.TemplateMessageService;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExpenseServiceProjectImpl extends ExpenseServiceImpl {
|
||||
|
||||
@Inject
|
||||
public ExpenseServiceProjectImpl(
|
||||
MoveService moveService,
|
||||
ExpenseRepository expenseRepository,
|
||||
MoveLineService moveLineService,
|
||||
AccountManagementAccountService accountManagementAccountService,
|
||||
AppAccountService appAccountService,
|
||||
AccountConfigHRService accountConfigService,
|
||||
AccountingSituationService accountingSituationService,
|
||||
AnalyticMoveLineService analyticMoveLineService,
|
||||
HRConfigService hrConfigService,
|
||||
TemplateMessageService templateMessageService,
|
||||
PaymentModeService paymentModeService) {
|
||||
|
||||
super(
|
||||
moveService,
|
||||
expenseRepository,
|
||||
moveLineService,
|
||||
accountManagementAccountService,
|
||||
appAccountService,
|
||||
accountConfigService,
|
||||
accountingSituationService,
|
||||
analyticMoveLineService,
|
||||
hrConfigService,
|
||||
templateMessageService,
|
||||
paymentModeService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> createInvoiceLines(
|
||||
Invoice invoice, List<ExpenseLine> expenseLineList, int priority) throws AxelorException {
|
||||
|
||||
List<InvoiceLine> invoiceLineList = new ArrayList<InvoiceLine>();
|
||||
int count = 0;
|
||||
for (ExpenseLine expenseLine : expenseLineList) {
|
||||
|
||||
invoiceLineList.addAll(this.createInvoiceLine(invoice, expenseLine, priority * 100 + count));
|
||||
count++;
|
||||
invoiceLineList.get(invoiceLineList.size() - 1).setProject(expenseLine.getProject());
|
||||
}
|
||||
|
||||
return invoiceLineList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import java.util.List;
|
||||
|
||||
public interface InvoiceLineProjectService {
|
||||
|
||||
public void setProject(List<Long> invoiceLineIds, Project project);
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.AnalyticMoveLine;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.db.repo.InvoiceLineRepository;
|
||||
import com.axelor.apps.account.service.AccountManagementAccountService;
|
||||
import com.axelor.apps.account.service.AnalyticMoveLineService;
|
||||
import com.axelor.apps.account.service.app.AppAccountService;
|
||||
import com.axelor.apps.base.service.CurrencyService;
|
||||
import com.axelor.apps.base.service.PriceListService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.purchase.service.PurchaseProductService;
|
||||
import com.axelor.apps.supplychain.service.InvoiceLineSupplychainService;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
|
||||
public class InvoiceLineProjectServiceImpl extends InvoiceLineSupplychainService
|
||||
implements InvoiceLineProjectService {
|
||||
|
||||
@Inject private InvoiceLineRepository invoiceLineRepo;
|
||||
|
||||
@Inject
|
||||
public InvoiceLineProjectServiceImpl(
|
||||
CurrencyService currencyService,
|
||||
PriceListService priceListService,
|
||||
AppAccountService appAccountService,
|
||||
AnalyticMoveLineService analyticMoveLineService,
|
||||
AccountManagementAccountService accountManagementAccountService,
|
||||
PurchaseProductService purchaseProductService) {
|
||||
super(
|
||||
currencyService,
|
||||
priceListService,
|
||||
appAccountService,
|
||||
analyticMoveLineService,
|
||||
accountManagementAccountService,
|
||||
purchaseProductService);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void setProject(List<Long> invoiceLineIds, Project project) {
|
||||
|
||||
if (invoiceLineIds != null) {
|
||||
|
||||
List<InvoiceLine> invoiceLineList =
|
||||
invoiceLineRepo.all().filter("self.id in ?1", invoiceLineIds).fetch();
|
||||
|
||||
for (InvoiceLine line : invoiceLineList) {
|
||||
line.setProject(project);
|
||||
invoiceLineRepo.save(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnalyticMoveLine> createAnalyticDistributionWithTemplate(InvoiceLine invoiceLine) {
|
||||
List<AnalyticMoveLine> analyticMoveLineList =
|
||||
super.createAnalyticDistributionWithTemplate(invoiceLine);
|
||||
|
||||
if (invoiceLine.getProject() != null && analyticMoveLineList != null) {
|
||||
analyticMoveLineList.forEach(
|
||||
analyticLine -> analyticLine.setProject(invoiceLine.getProject()));
|
||||
}
|
||||
return analyticMoveLineList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoicePayment;
|
||||
import com.axelor.apps.account.db.repo.InvoicePaymentRepository;
|
||||
import com.axelor.apps.account.service.ReconcileService;
|
||||
import com.axelor.apps.account.service.config.AccountConfigService;
|
||||
import com.axelor.apps.account.service.move.MoveLineService;
|
||||
import com.axelor.apps.account.service.move.MoveService;
|
||||
import com.axelor.apps.account.service.payment.PaymentModeService;
|
||||
import com.axelor.apps.account.service.payment.invoice.payment.InvoicePaymentToolService;
|
||||
import com.axelor.apps.bankpayment.service.bankorder.BankOrderCreateService;
|
||||
import com.axelor.apps.bankpayment.service.bankorder.BankOrderService;
|
||||
import com.axelor.apps.bankpayment.service.invoice.payment.InvoicePaymentValidateServiceBankPayImpl;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectRepository;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.io.IOException;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.datatype.DatatypeConfigurationException;
|
||||
|
||||
public class InvoicePaymentValidateProjectServiceImpl
|
||||
extends InvoicePaymentValidateServiceBankPayImpl {
|
||||
|
||||
private InvoicingProjectRepository invoicingProjectRepo;
|
||||
|
||||
@Inject
|
||||
public InvoicePaymentValidateProjectServiceImpl(
|
||||
PaymentModeService paymentModeService,
|
||||
MoveService moveService,
|
||||
MoveLineService moveLineService,
|
||||
AccountConfigService accountConfigService,
|
||||
InvoicePaymentRepository invoicePaymentRepository,
|
||||
ReconcileService reconcileService,
|
||||
BankOrderCreateService bankOrderCreateService,
|
||||
BankOrderService bankOrderService,
|
||||
InvoicePaymentToolService invoicePaymentToolService,
|
||||
InvoicingProjectRepository invoicingProjectRepo) {
|
||||
super(
|
||||
paymentModeService,
|
||||
moveService,
|
||||
moveLineService,
|
||||
accountConfigService,
|
||||
invoicePaymentRepository,
|
||||
reconcileService,
|
||||
bankOrderCreateService,
|
||||
bankOrderService,
|
||||
invoicePaymentToolService);
|
||||
this.invoicingProjectRepo = invoicingProjectRepo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public void validate(InvoicePayment invoicePayment, boolean force)
|
||||
throws AxelorException, JAXBException, IOException, DatatypeConfigurationException {
|
||||
super.validate(invoicePayment, force);
|
||||
Invoice invoice = invoicePayment.getInvoice();
|
||||
|
||||
InvoicingProject invoicingProject =
|
||||
invoicingProjectRepo
|
||||
.all()
|
||||
.filter(
|
||||
"self.invoice.id = ?1 AND self.project.invoicingSequenceSelect = ?2",
|
||||
invoice.getId(),
|
||||
ProjectRepository.INVOICING_SEQ_INVOICE_PRE_TASK)
|
||||
.fetchOne();
|
||||
|
||||
if (invoicingProject != null) {
|
||||
for (TeamTask teamTask : invoicingProject.getTeamTaskSet()) {
|
||||
teamTask.setIsPaid(invoice.getHasPendingPayments());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.ReportFactory;
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.repo.InvoiceRepository;
|
||||
import com.axelor.apps.account.exception.IExceptionMessage;
|
||||
import com.axelor.apps.account.service.app.AppAccountService;
|
||||
import com.axelor.apps.account.service.config.AccountConfigService;
|
||||
import com.axelor.apps.account.service.invoice.InvoiceLineService;
|
||||
import com.axelor.apps.account.service.invoice.factory.CancelFactory;
|
||||
import com.axelor.apps.account.service.invoice.factory.ValidateFactory;
|
||||
import com.axelor.apps.account.service.invoice.factory.VentilateFactory;
|
||||
import com.axelor.apps.base.service.PartnerService;
|
||||
import com.axelor.apps.base.service.alarm.AlarmEngineService;
|
||||
import com.axelor.apps.businessproject.report.IReport;
|
||||
import com.axelor.apps.report.engine.ReportSettings;
|
||||
import com.axelor.apps.supplychain.service.invoice.InvoiceServiceSupplychainImpl;
|
||||
import com.axelor.auth.AuthUtils;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class InvoiceServiceProjectImpl extends InvoiceServiceSupplychainImpl {
|
||||
|
||||
@Inject
|
||||
public InvoiceServiceProjectImpl(
|
||||
ValidateFactory validateFactory,
|
||||
VentilateFactory ventilateFactory,
|
||||
CancelFactory cancelFactory,
|
||||
AlarmEngineService<Invoice> alarmEngineService,
|
||||
InvoiceRepository invoiceRepo,
|
||||
AppAccountService appAccountService,
|
||||
PartnerService partnerService,
|
||||
InvoiceLineService invoiceLineService,
|
||||
AccountConfigService accountConfigService) {
|
||||
super(
|
||||
validateFactory,
|
||||
ventilateFactory,
|
||||
cancelFactory,
|
||||
alarmEngineService,
|
||||
invoiceRepo,
|
||||
appAccountService,
|
||||
partnerService,
|
||||
invoiceLineService,
|
||||
accountConfigService);
|
||||
}
|
||||
|
||||
public List<String> editInvoiceAnnex(Invoice invoice, String invoiceIds, boolean toAttach)
|
||||
throws AxelorException {
|
||||
|
||||
if (invoice.getPrintingSettings() == null) {
|
||||
throw new AxelorException(
|
||||
TraceBackRepository.CATEGORY_MISSING_FIELD,
|
||||
String.format(
|
||||
I18n.get(IExceptionMessage.INVOICE_MISSING_PRINTING_SETTINGS),
|
||||
invoice.getInvoiceId()),
|
||||
invoice);
|
||||
}
|
||||
|
||||
if (!AuthUtils.getUser().getActiveCompany().getAccountConfig().getDisplayTimesheetOnPrinting()
|
||||
&& !AuthUtils.getUser()
|
||||
.getActiveCompany()
|
||||
.getAccountConfig()
|
||||
.getDisplayExpenseOnPrinting()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String language = ReportSettings.getPrintingLocale(invoice.getPartner());
|
||||
|
||||
String title = I18n.get("Invoice");
|
||||
if (invoice.getInvoiceId() != null) {
|
||||
title += invoice.getInvoiceId();
|
||||
}
|
||||
|
||||
Integer invoicesCopy = invoice.getInvoicesCopySelect();
|
||||
ReportSettings rS =
|
||||
ReportFactory.createReport(
|
||||
IReport.INVOICE_ANNEX, title + "-" + I18n.get("Annex") + "-${date}");
|
||||
|
||||
if (toAttach) {
|
||||
rS.toAttach(invoice);
|
||||
}
|
||||
|
||||
String fileLink =
|
||||
rS.addParam("InvoiceId", invoiceIds)
|
||||
.addParam("Locale", language)
|
||||
.addParam("InvoicesCopy", invoicesCopy)
|
||||
.addParam("HeaderHeight", invoice.getPrintingSettings().getPdfHeaderHeight())
|
||||
.addParam("FooterHeight", invoice.getPrintingSettings().getPdfFooterHeight())
|
||||
.generate()
|
||||
.getFileLink();
|
||||
|
||||
List<String> res = Arrays.asList(title, fileLink);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.ReportFactory;
|
||||
import com.axelor.apps.account.db.AccountConfig;
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.db.repo.InvoiceRepository;
|
||||
import com.axelor.apps.account.service.config.AccountConfigService;
|
||||
import com.axelor.apps.account.service.invoice.generator.InvoiceGenerator;
|
||||
import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator;
|
||||
import com.axelor.apps.account.service.invoice.print.InvoicePrintServiceImpl;
|
||||
import com.axelor.apps.account.util.InvoiceLineComparator;
|
||||
import com.axelor.apps.base.db.Company;
|
||||
import com.axelor.apps.base.db.Partner;
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.base.db.repo.PriceListRepository;
|
||||
import com.axelor.apps.base.service.PartnerPriceListService;
|
||||
import com.axelor.apps.base.service.PartnerService;
|
||||
import com.axelor.apps.base.service.app.AppBaseService;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectRepository;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.report.IReport;
|
||||
import com.axelor.apps.hr.db.ExpenseLine;
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.apps.hr.db.repo.ExpenseLineRepository;
|
||||
import com.axelor.apps.hr.db.repo.ExpenseRepository;
|
||||
import com.axelor.apps.hr.db.repo.TimesheetLineRepository;
|
||||
import com.axelor.apps.hr.service.expense.ExpenseService;
|
||||
import com.axelor.apps.hr.service.timesheet.TimesheetService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.project.service.ProjectServiceImpl;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrderLine;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
|
||||
import com.axelor.apps.report.engine.ReportSettings;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderLineRepository;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
|
||||
import com.axelor.apps.supplychain.service.invoice.generator.InvoiceLineGeneratorSupplyChain;
|
||||
import com.axelor.apps.tool.file.PdfTool;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.MetaFiles;
|
||||
import com.axelor.meta.db.MetaFile;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InvoicingProjectService {
|
||||
|
||||
@Inject protected TimesheetService timesheetService;
|
||||
|
||||
@Inject protected ExpenseService expenseService;
|
||||
|
||||
@Inject protected PartnerService partnerService;
|
||||
|
||||
@Inject protected TeamTaskBusinessProjectService teamTaskBusinessProjectService;
|
||||
|
||||
@Inject protected InvoicingProjectRepository invoicingProjectRepo;
|
||||
|
||||
protected int MAX_LEVEL_OF_PROJECT = 10;
|
||||
|
||||
protected int sequence = 0;
|
||||
|
||||
protected static final String DATE_FORMAT_YYYYMMDDHHMM = "YYYYMMddHHmm";
|
||||
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public Invoice generateInvoice(InvoicingProject invoicingProject) throws AxelorException {
|
||||
Project project = invoicingProject.getProject();
|
||||
Partner customer = project.getClientPartner();
|
||||
Partner customerContact = project.getContactPartner();
|
||||
if (customerContact == null && customer.getContactPartnerSet().size() == 1) {
|
||||
customerContact = customer.getContactPartnerSet().iterator().next();
|
||||
}
|
||||
Company company = this.getRootCompany(project);
|
||||
if (company == null) {
|
||||
throw new AxelorException(
|
||||
invoicingProject,
|
||||
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
|
||||
I18n.get(IExceptionMessage.INVOICING_PROJECT_PROJECT_COMPANY));
|
||||
}
|
||||
InvoiceGenerator invoiceGenerator =
|
||||
new InvoiceGenerator(
|
||||
InvoiceRepository.OPERATION_TYPE_CLIENT_SALE,
|
||||
company,
|
||||
customer.getPaymentCondition(),
|
||||
customer.getInPaymentMode(),
|
||||
partnerService.getInvoicingAddress(customer),
|
||||
customer,
|
||||
customerContact,
|
||||
customer.getCurrency(),
|
||||
Beans.get(PartnerPriceListService.class)
|
||||
.getDefaultPriceList(customer, PriceListRepository.TYPE_SALE),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null) {
|
||||
|
||||
@Override
|
||||
public Invoice generate() throws AxelorException {
|
||||
|
||||
Invoice invoice = super.createInvoiceHeader();
|
||||
invoice.setProject(project);
|
||||
invoice.setPriceList(project.getPriceList());
|
||||
return invoice;
|
||||
}
|
||||
};
|
||||
Invoice invoice = invoiceGenerator.generate();
|
||||
AccountConfigService accountConfigService = Beans.get(AccountConfigService.class);
|
||||
AccountConfig accountConfig = accountConfigService.getAccountConfig(company);
|
||||
invoice.setDisplayTimesheetOnPrinting(accountConfig.getDisplayTimesheetOnPrinting());
|
||||
invoice.setDisplayExpenseOnPrinting(accountConfig.getDisplayExpenseOnPrinting());
|
||||
|
||||
invoiceGenerator.populate(invoice, this.populate(invoice, invoicingProject));
|
||||
Beans.get(InvoiceRepository.class).save(invoice);
|
||||
|
||||
invoicingProject.setInvoice(invoice);
|
||||
invoicingProject.setStatusSelect(InvoicingProjectRepository.STATUS_GENERATED);
|
||||
invoicingProjectRepo.save(invoicingProject);
|
||||
return invoice;
|
||||
}
|
||||
|
||||
public List<InvoiceLine> populate(Invoice invoice, InvoicingProject folder)
|
||||
throws AxelorException {
|
||||
List<SaleOrderLine> saleOrderLineList =
|
||||
new ArrayList<SaleOrderLine>(folder.getSaleOrderLineSet());
|
||||
List<PurchaseOrderLine> purchaseOrderLineList =
|
||||
new ArrayList<PurchaseOrderLine>(folder.getPurchaseOrderLineSet());
|
||||
List<TimesheetLine> timesheetLineList = new ArrayList<TimesheetLine>(folder.getLogTimesSet());
|
||||
List<ExpenseLine> expenseLineList = new ArrayList<ExpenseLine>(folder.getExpenseLineSet());
|
||||
List<TeamTask> teamTaskList = new ArrayList<TeamTask>(folder.getTeamTaskSet());
|
||||
|
||||
List<InvoiceLine> invoiceLineList = new ArrayList<InvoiceLine>();
|
||||
invoiceLineList.addAll(
|
||||
this.createSaleOrderInvoiceLines(
|
||||
invoice, saleOrderLineList, folder.getSaleOrderLineSetPrioritySelect()));
|
||||
invoiceLineList.addAll(
|
||||
this.createPurchaseOrderInvoiceLines(
|
||||
invoice, purchaseOrderLineList, folder.getPurchaseOrderLineSetPrioritySelect()));
|
||||
invoiceLineList.addAll(
|
||||
timesheetService.createInvoiceLines(
|
||||
invoice, timesheetLineList, folder.getLogTimesSetPrioritySelect()));
|
||||
invoiceLineList.addAll(
|
||||
expenseService.createInvoiceLines(
|
||||
invoice, expenseLineList, folder.getExpenseLineSetPrioritySelect()));
|
||||
invoiceLineList.addAll(
|
||||
teamTaskBusinessProjectService.createInvoiceLines(
|
||||
invoice, teamTaskList, folder.getTeamTaskSetPrioritySelect()));
|
||||
|
||||
Collections.sort(invoiceLineList, new InvoiceLineComparator());
|
||||
|
||||
for (InvoiceLine invoiceLine : invoiceLineList) {
|
||||
invoiceLine.setSequence(sequence);
|
||||
sequence++;
|
||||
}
|
||||
|
||||
return invoiceLineList;
|
||||
}
|
||||
|
||||
public List<InvoiceLine> createSaleOrderInvoiceLines(
|
||||
Invoice invoice, List<SaleOrderLine> saleOrderLineList, int priority) throws AxelorException {
|
||||
|
||||
List<InvoiceLine> invoiceLineList = new ArrayList<InvoiceLine>();
|
||||
int count = 1;
|
||||
for (SaleOrderLine saleOrderLine : saleOrderLineList) {
|
||||
|
||||
invoiceLineList.addAll(
|
||||
this.createInvoiceLine(invoice, saleOrderLine, priority * 100 + count));
|
||||
count++;
|
||||
}
|
||||
|
||||
return invoiceLineList;
|
||||
}
|
||||
|
||||
public List<InvoiceLine> createInvoiceLine(
|
||||
Invoice invoice, SaleOrderLine saleOrderLine, int priority) throws AxelorException {
|
||||
|
||||
Product product = saleOrderLine.getProduct();
|
||||
|
||||
InvoiceLineGenerator invoiceLineGenerator =
|
||||
new InvoiceLineGeneratorSupplyChain(
|
||||
invoice,
|
||||
product,
|
||||
saleOrderLine.getProductName(),
|
||||
saleOrderLine.getDescription(),
|
||||
saleOrderLine.getQty(),
|
||||
saleOrderLine.getUnit(),
|
||||
priority,
|
||||
false,
|
||||
saleOrderLine,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
0) {
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> creates() throws AxelorException {
|
||||
|
||||
InvoiceLine invoiceLine = this.createInvoiceLine();
|
||||
invoiceLine.setProject(saleOrderLine.getProject());
|
||||
List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
|
||||
invoiceLines.add(invoiceLine);
|
||||
|
||||
return invoiceLines;
|
||||
}
|
||||
};
|
||||
|
||||
return invoiceLineGenerator.creates();
|
||||
}
|
||||
|
||||
public List<InvoiceLine> createPurchaseOrderInvoiceLines(
|
||||
Invoice invoice, List<PurchaseOrderLine> purchaseOrderLineList, int priority)
|
||||
throws AxelorException {
|
||||
|
||||
List<InvoiceLine> invoiceLineList = new ArrayList<InvoiceLine>();
|
||||
for (PurchaseOrderLine purchaseOrderLine : purchaseOrderLineList) {
|
||||
|
||||
invoiceLineList.addAll(
|
||||
Beans.get(PurchaseOrderInvoiceProjectServiceImpl.class)
|
||||
.createInvoiceLine(invoice, purchaseOrderLine));
|
||||
}
|
||||
return invoiceLineList;
|
||||
}
|
||||
|
||||
public List<InvoiceLine> createInvoiceLine(
|
||||
Invoice invoice, PurchaseOrderLine purchaseOrderLine, int priority) throws AxelorException {
|
||||
|
||||
Product product = purchaseOrderLine.getProduct();
|
||||
|
||||
InvoiceLineGeneratorSupplyChain invoiceLineGenerator =
|
||||
new InvoiceLineGeneratorSupplyChain(
|
||||
invoice,
|
||||
product,
|
||||
purchaseOrderLine.getProductName(),
|
||||
purchaseOrderLine.getDescription(),
|
||||
purchaseOrderLine.getQty(),
|
||||
purchaseOrderLine.getUnit(),
|
||||
priority,
|
||||
false,
|
||||
null,
|
||||
purchaseOrderLine,
|
||||
null,
|
||||
false,
|
||||
0) {
|
||||
@Override
|
||||
public List<InvoiceLine> creates() throws AxelorException {
|
||||
|
||||
InvoiceLine invoiceLine = this.createInvoiceLine();
|
||||
|
||||
List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
|
||||
invoiceLines.add(invoiceLine);
|
||||
|
||||
return invoiceLines;
|
||||
}
|
||||
};
|
||||
|
||||
return invoiceLineGenerator.creates();
|
||||
}
|
||||
|
||||
public void setLines(InvoicingProject invoicingProject, Project project, int counter) {
|
||||
|
||||
if (counter > ProjectServiceImpl.MAX_LEVEL_OF_PROJECT) {
|
||||
return;
|
||||
}
|
||||
counter++;
|
||||
|
||||
this.fillLines(invoicingProject, project);
|
||||
|
||||
List<Project> projectChildrenList =
|
||||
Beans.get(ProjectRepository.class).all().filter("self.parentProject = ?1", project).fetch();
|
||||
|
||||
for (Project projectChild : projectChildrenList) {
|
||||
this.setLines(invoicingProject, projectChild, counter);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public void fillLines(InvoicingProject invoicingProject, Project project) {
|
||||
String commonQuery =
|
||||
"self.project = :project AND self.toInvoice = true AND self.invoiced = false";
|
||||
|
||||
StringBuilder solQueryBuilder = new StringBuilder(commonQuery);
|
||||
solQueryBuilder.append(
|
||||
" AND (self.saleOrder.statusSelect = :statusConfirmed OR self.saleOrder.statusSelect = :statusCompleted)");
|
||||
|
||||
Map<String, Object> solQueryMap = new HashMap<>();
|
||||
solQueryMap.put("project", project);
|
||||
solQueryMap.put("statusConfirmed", SaleOrderRepository.STATUS_ORDER_CONFIRMED);
|
||||
solQueryMap.put("statusCompleted", SaleOrderRepository.STATUS_ORDER_COMPLETED);
|
||||
|
||||
StringBuilder polQueryBuilder = new StringBuilder(commonQuery);
|
||||
polQueryBuilder.append(
|
||||
" AND (self.purchaseOrder.statusSelect = 3 OR self.purchaseOrder.statusSelect = 4)");
|
||||
|
||||
Map<String, Object> polQueryMap = new HashMap<>();
|
||||
polQueryMap.put("project", project);
|
||||
|
||||
StringBuilder logTimesQueryBuilder = new StringBuilder(commonQuery);
|
||||
|
||||
Map<String, Object> logTimesQueryMap = new HashMap<>();
|
||||
logTimesQueryMap.put("project", project);
|
||||
|
||||
StringBuilder expenseLineQueryBuilder = new StringBuilder(commonQuery);
|
||||
expenseLineQueryBuilder.append(
|
||||
" AND (self.expense.statusSelect = :statusValidated OR self.expense.statusSelect = :statusReimbursed)");
|
||||
|
||||
Map<String, Object> expenseLineQueryMap = new HashMap<>();
|
||||
expenseLineQueryMap.put("project", project);
|
||||
expenseLineQueryMap.put("statusValidated", ExpenseRepository.STATUS_VALIDATED);
|
||||
expenseLineQueryMap.put("statusReimbursed", ExpenseRepository.STATUS_REIMBURSED);
|
||||
|
||||
StringBuilder taskQueryBuilder = new StringBuilder(commonQuery);
|
||||
taskQueryBuilder.append(" AND self.invoicingType = :invoicingTypePackage");
|
||||
|
||||
Map<String, Object> taskQueryMap = new HashMap<>();
|
||||
taskQueryMap.put("project", project);
|
||||
taskQueryMap.put("invoicingTypePackage", TeamTaskRepository.INVOICING_TYPE_PACKAGE);
|
||||
|
||||
if (invoicingProject.getDeadlineDate() != null) {
|
||||
solQueryBuilder.append(" AND self.saleOrder.creationDate < :deadlineDate");
|
||||
solQueryMap.put("deadlineDate", invoicingProject.getDeadlineDate());
|
||||
|
||||
polQueryBuilder.append(" AND self.purchaseOrder.orderDate < :deadlineDate");
|
||||
polQueryMap.put("deadlineDate", invoicingProject.getDeadlineDate());
|
||||
|
||||
logTimesQueryBuilder.append(" AND self.date < :deadlineDate");
|
||||
logTimesQueryMap.put("deadlineDate", invoicingProject.getDeadlineDate());
|
||||
|
||||
expenseLineQueryBuilder.append(" AND self.expenseDate < :deadlineDate");
|
||||
expenseLineQueryMap.put("deadlineDate", invoicingProject.getDeadlineDate());
|
||||
|
||||
taskQueryBuilder.append(" AND self.taskDeadline < :deadlineDate");
|
||||
taskQueryMap.put("deadlineDate", invoicingProject.getDeadlineDate());
|
||||
}
|
||||
|
||||
invoicingProject
|
||||
.getSaleOrderLineSet()
|
||||
.addAll(
|
||||
Beans.get(SaleOrderLineRepository.class)
|
||||
.all()
|
||||
.filter(solQueryBuilder.toString())
|
||||
.bind(solQueryMap)
|
||||
.fetch());
|
||||
|
||||
invoicingProject
|
||||
.getPurchaseOrderLineSet()
|
||||
.addAll(
|
||||
Beans.get(PurchaseOrderLineRepository.class)
|
||||
.all()
|
||||
.filter(polQueryBuilder.toString())
|
||||
.bind(polQueryMap)
|
||||
.fetch());
|
||||
|
||||
invoicingProject
|
||||
.getLogTimesSet()
|
||||
.addAll(
|
||||
Beans.get(TimesheetLineRepository.class)
|
||||
.all()
|
||||
.filter(logTimesQueryBuilder.toString())
|
||||
.bind(logTimesQueryMap)
|
||||
.fetch());
|
||||
|
||||
invoicingProject
|
||||
.getExpenseLineSet()
|
||||
.addAll(
|
||||
Beans.get(ExpenseLineRepository.class)
|
||||
.all()
|
||||
.filter(expenseLineQueryBuilder.toString())
|
||||
.bind(expenseLineQueryMap)
|
||||
.fetch());
|
||||
|
||||
invoicingProject
|
||||
.getTeamTaskSet()
|
||||
.addAll(
|
||||
Beans.get(TeamTaskRepository.class)
|
||||
.all()
|
||||
.filter(taskQueryBuilder.toString())
|
||||
.bind(taskQueryMap)
|
||||
.fetch());
|
||||
}
|
||||
|
||||
public void clearLines(InvoicingProject invoicingProject) {
|
||||
|
||||
invoicingProject.setSaleOrderLineSet(new HashSet<SaleOrderLine>());
|
||||
invoicingProject.setPurchaseOrderLineSet(new HashSet<PurchaseOrderLine>());
|
||||
invoicingProject.setLogTimesSet(new HashSet<TimesheetLine>());
|
||||
invoicingProject.setExpenseLineSet(new HashSet<ExpenseLine>());
|
||||
invoicingProject.setProjectSet(new HashSet<Project>());
|
||||
invoicingProject.setTeamTaskSet(new HashSet<TeamTask>());
|
||||
}
|
||||
|
||||
public Company getRootCompany(Project project) {
|
||||
if (project.getParentProject() == null) {
|
||||
return project.getCompany();
|
||||
} else {
|
||||
return getRootCompany(project.getParentProject());
|
||||
}
|
||||
}
|
||||
|
||||
public int countToInvoice(Project project) {
|
||||
|
||||
int toInvoiceCount = 0;
|
||||
|
||||
String query = "self.project = ?1";
|
||||
|
||||
if (project.getIsShowPhasesElements()) {
|
||||
query = "(self.project = ?1 OR self.project.parentProject = ?1)";
|
||||
}
|
||||
|
||||
query += " AND self.toInvoice = true AND self.invoiced = false";
|
||||
|
||||
toInvoiceCount += Beans.get(SaleOrderLineRepository.class).all().filter(query, project).count();
|
||||
|
||||
toInvoiceCount +=
|
||||
Beans.get(PurchaseOrderLineRepository.class).all().filter(query, project).count();
|
||||
|
||||
toInvoiceCount += Beans.get(ExpenseLineRepository.class).all().filter(query, project).count();
|
||||
|
||||
toInvoiceCount += Beans.get(TimesheetLineRepository.class).all().filter(query, project).count();
|
||||
|
||||
toInvoiceCount += Beans.get(TeamTaskRepository.class).all().filter(query, project).count();
|
||||
|
||||
return toInvoiceCount;
|
||||
}
|
||||
|
||||
public void generateAnnex(InvoicingProject invoicingProject) throws AxelorException, IOException {
|
||||
String title =
|
||||
I18n.get("InvoicingProjectAnnex")
|
||||
+ "-"
|
||||
+ Beans.get(AppBaseService.class)
|
||||
.getTodayDateTime()
|
||||
.format(DateTimeFormatter.ofPattern(DATE_FORMAT_YYYYMMDDHHMM));
|
||||
|
||||
ReportSettings reportSettings =
|
||||
ReportFactory.createReport(IReport.INVOICING_PROJECT_ANNEX, title)
|
||||
.addParam("InvProjectId", invoicingProject.getId())
|
||||
.addParam("Locale", ReportSettings.getPrintingLocale(null));
|
||||
|
||||
if (invoicingProject.getAttachAnnexToInvoice()) {
|
||||
List<File> fileList = new ArrayList<>();
|
||||
MetaFiles metaFiles = Beans.get(MetaFiles.class);
|
||||
|
||||
fileList.add(
|
||||
Beans.get(InvoicePrintServiceImpl.class)
|
||||
.print(invoicingProject.getInvoice(), null, ReportSettings.FORMAT_PDF, null));
|
||||
fileList.add(reportSettings.generate().getFile());
|
||||
|
||||
MetaFile metaFile = metaFiles.upload(PdfTool.mergePdf(fileList));
|
||||
metaFile.setFileName(title + ".pdf");
|
||||
metaFiles.attach(metaFile, null, invoicingProject);
|
||||
return;
|
||||
}
|
||||
reportSettings.toAttach(invoicingProject).generate();
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {AxelorException.class, Exception.class})
|
||||
public InvoicingProject generateInvoicingProject(Project project) {
|
||||
if (project == null) {
|
||||
return null;
|
||||
}
|
||||
InvoicingProject invoicingProject = new InvoicingProject();
|
||||
invoicingProject.setProject(project);
|
||||
clearLines(invoicingProject);
|
||||
setLines(invoicingProject, project, 0);
|
||||
|
||||
if (invoicingProject.getSaleOrderLineSet().isEmpty()
|
||||
&& invoicingProject.getPurchaseOrderLineSet().isEmpty()
|
||||
&& invoicingProject.getLogTimesSet().isEmpty()
|
||||
&& invoicingProject.getExpenseLineSet().isEmpty()
|
||||
&& invoicingProject.getProjectSet().isEmpty()
|
||||
&& invoicingProject.getTeamTaskSet().isEmpty()) {
|
||||
|
||||
return invoicingProject;
|
||||
}
|
||||
return invoicingProjectRepo.save(invoicingProject);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.TaskTemplate;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public interface ProductTaskTemplateService {
|
||||
|
||||
/**
|
||||
* Convert task template list to team task list. This method is recursive.
|
||||
*
|
||||
* @param templates List of task template to use for convert.
|
||||
* @param project Project to set for each team task.
|
||||
* @param parent Parent task
|
||||
* @param startDate The start date for tasks.
|
||||
* @param qty The number copy of the task.
|
||||
* @return List of team task convert.
|
||||
*/
|
||||
List<TeamTask> convert(
|
||||
List<? extends TaskTemplate> templates,
|
||||
Project project,
|
||||
TeamTask parent,
|
||||
LocalDateTime startDate,
|
||||
BigDecimal qty,
|
||||
SaleOrderLine saleOrderLine);
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.TaskTemplate;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ProductTaskTemplateServiceImpl implements ProductTaskTemplateService {
|
||||
|
||||
protected TeamTaskBusinessProjectService teamTaskBusinessProjectService;
|
||||
protected TeamTaskRepository teamTaskRepository;
|
||||
|
||||
@Inject
|
||||
public ProductTaskTemplateServiceImpl(
|
||||
TeamTaskBusinessProjectService teamTaskBusinessProjectService,
|
||||
TeamTaskRepository teamTaskRepository) {
|
||||
this.teamTaskBusinessProjectService = teamTaskBusinessProjectService;
|
||||
this.teamTaskRepository = teamTaskRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<TeamTask> convert(
|
||||
List<? extends TaskTemplate> templates,
|
||||
Project project,
|
||||
TeamTask parent,
|
||||
LocalDateTime startDate,
|
||||
BigDecimal qty,
|
||||
SaleOrderLine saleOrderLine) {
|
||||
List<TeamTask> tasks = new ArrayList<>();
|
||||
Product product = saleOrderLine.getProduct();
|
||||
|
||||
for (TaskTemplate template : templates) {
|
||||
BigDecimal qtyTmp = (template.getIsUniqueTaskForMultipleQuantity() ? BigDecimal.ONE : qty);
|
||||
|
||||
while (qtyTmp.signum() > 0) {
|
||||
LocalDateTime dateWithDelay = startDate.plusHours(template.getDelayToStart().longValue());
|
||||
|
||||
TeamTask task =
|
||||
teamTaskBusinessProjectService.create(template, project, dateWithDelay, qty);
|
||||
task.setParentTask(parent);
|
||||
task.setProduct(product);
|
||||
task.setQuantity(!template.getIsUniqueTaskForMultipleQuantity() ? BigDecimal.ONE : qty);
|
||||
task.setUnit(product.getUnit());
|
||||
task.setUnitPrice(product.getSalePrice());
|
||||
task.setExTaxTotal(task.getUnitPrice().multiply(task.getQuantity()));
|
||||
if (saleOrderLine.getSaleOrder().getToInvoiceViaTask()) {
|
||||
task.setToInvoice(true);
|
||||
task.setInvoicingType(TeamTaskRepository.INVOICING_TYPE_PACKAGE);
|
||||
}
|
||||
tasks.add(teamTaskRepository.save(task));
|
||||
|
||||
// Only parent task can have multiple quantities
|
||||
List<TeamTask> children =
|
||||
convert(
|
||||
template.getTaskTemplateList(),
|
||||
project,
|
||||
task,
|
||||
dateWithDelay,
|
||||
BigDecimal.ONE,
|
||||
saleOrderLine);
|
||||
tasks.addAll(children);
|
||||
|
||||
qtyTmp = qtyTmp.subtract(BigDecimal.ONE);
|
||||
}
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.service.ProjectService;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.exception.AxelorException;
|
||||
|
||||
public interface ProjectBusinessService extends ProjectService {
|
||||
|
||||
SaleOrder generateQuotation(Project project) throws AxelorException;
|
||||
|
||||
Project generateProject(SaleOrder saleOrder);
|
||||
|
||||
Project generatePhaseProject(SaleOrderLine saleOrderLine, Project parent);
|
||||
}
|
||||
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.service.AccountingSituationService;
|
||||
import com.axelor.apps.base.db.AppSupplychain;
|
||||
import com.axelor.apps.base.db.Company;
|
||||
import com.axelor.apps.base.db.Partner;
|
||||
import com.axelor.apps.base.db.repo.CompanyRepository;
|
||||
import com.axelor.apps.base.db.repo.PriceListRepository;
|
||||
import com.axelor.apps.base.service.AddressService;
|
||||
import com.axelor.apps.base.service.DurationService;
|
||||
import com.axelor.apps.base.service.PartnerPriceListService;
|
||||
import com.axelor.apps.base.service.PartnerService;
|
||||
import com.axelor.apps.businessproject.service.app.AppBusinessProjectService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.ProjectTemplate;
|
||||
import com.axelor.apps.project.db.TaskTemplate;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.project.service.ProjectServiceImpl;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
|
||||
import com.axelor.apps.sale.service.saleorder.SaleOrderCreateService;
|
||||
import com.axelor.apps.supplychain.service.app.AppSupplychainService;
|
||||
import com.axelor.auth.db.User;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
|
||||
public class ProjectBusinessServiceImpl extends ProjectServiceImpl
|
||||
implements ProjectBusinessService {
|
||||
|
||||
@Inject protected AppBusinessProjectService appBusinessProjectService;
|
||||
|
||||
@Inject protected ProjectRepository projectRepo;
|
||||
|
||||
@Inject protected PartnerService partnerService;
|
||||
|
||||
@Inject protected AddressService addressService;
|
||||
|
||||
@Inject
|
||||
public ProjectBusinessServiceImpl(ProjectRepository projectRepository) {
|
||||
super(projectRepository);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public SaleOrder generateQuotation(Project project) throws AxelorException {
|
||||
SaleOrder order = Beans.get(SaleOrderCreateService.class).createSaleOrder(project.getCompany());
|
||||
|
||||
Partner clientPartner = project.getClientPartner();
|
||||
Partner contactPartner = project.getContactPartner();
|
||||
if (contactPartner == null && clientPartner.getContactPartnerSet().size() == 1) {
|
||||
contactPartner = clientPartner.getContactPartnerSet().iterator().next();
|
||||
}
|
||||
|
||||
Company company = project.getCompany();
|
||||
|
||||
order.setProject(projectRepo.find(project.getId()));
|
||||
order.setClientPartner(clientPartner);
|
||||
order.setContactPartner(contactPartner);
|
||||
order.setCompany(company);
|
||||
|
||||
order.setMainInvoicingAddress(partnerService.getInvoicingAddress(clientPartner));
|
||||
order.setMainInvoicingAddressStr(
|
||||
addressService.computeAddressStr(order.getMainInvoicingAddress()));
|
||||
order.setDeliveryAddress(partnerService.getDeliveryAddress(clientPartner));
|
||||
order.setDeliveryAddressStr(addressService.computeAddressStr(order.getDeliveryAddress()));
|
||||
order.setIsNeedingConformityCertificate(clientPartner.getIsNeedingConformityCertificate());
|
||||
order.setCompanyBankDetails(
|
||||
Beans.get(AccountingSituationService.class)
|
||||
.getCompanySalesBankDetails(company, clientPartner));
|
||||
|
||||
if (project.getCurrency() != null) {
|
||||
order.setCurrency(project.getCurrency());
|
||||
} else if (clientPartner.getCurrency() != null) {
|
||||
order.setCurrency(clientPartner.getCurrency());
|
||||
} else {
|
||||
order.setCurrency(company.getCurrency());
|
||||
}
|
||||
|
||||
if (project.getPriceList() != null) {
|
||||
order.setPriceList(project.getPriceList());
|
||||
} else {
|
||||
order.setPriceList(
|
||||
Beans.get(PartnerPriceListService.class)
|
||||
.getDefaultPriceList(clientPartner, PriceListRepository.TYPE_SALE));
|
||||
}
|
||||
|
||||
if (order.getPriceList() != null) {
|
||||
order.setHideDiscount(order.getPriceList().getHideDiscount());
|
||||
}
|
||||
|
||||
if (clientPartner.getPaymentCondition() != null) {
|
||||
order.setPaymentCondition(clientPartner.getPaymentCondition());
|
||||
} else {
|
||||
if (company != null && company.getAccountConfig() != null) {
|
||||
order.setPaymentCondition(company.getAccountConfig().getDefPaymentCondition());
|
||||
}
|
||||
}
|
||||
|
||||
if (clientPartner.getInPaymentMode() != null) {
|
||||
order.setPaymentMode(clientPartner.getInPaymentMode());
|
||||
} else {
|
||||
if (company != null && company.getAccountConfig() != null) {
|
||||
order.setPaymentMode(company.getAccountConfig().getInPaymentMode());
|
||||
}
|
||||
}
|
||||
|
||||
if (order.getDuration() != null && order.getCreationDate() != null) {
|
||||
order.setEndOfValidityDate(
|
||||
Beans.get(DurationService.class)
|
||||
.computeDuration(order.getDuration(), order.getCreationDate()));
|
||||
}
|
||||
|
||||
AppSupplychain appSupplychain = Beans.get(AppSupplychainService.class).getAppSupplychain();
|
||||
if (appSupplychain != null) {
|
||||
order.setShipmentMode(clientPartner.getShipmentMode());
|
||||
order.setFreightCarrierMode(clientPartner.getFreightCarrierMode());
|
||||
if (clientPartner.getFreightCarrierMode() != null) {
|
||||
order.setCarrierPartner(clientPartner.getFreightCarrierMode().getCarrierPartner());
|
||||
}
|
||||
Boolean interco =
|
||||
appSupplychain.getIntercoFromSale()
|
||||
&& !order.getCreatedByInterco()
|
||||
&& clientPartner != null
|
||||
&& Beans.get(CompanyRepository.class)
|
||||
.all()
|
||||
.filter("self.partner = ?", clientPartner)
|
||||
.fetchOne()
|
||||
!= null;
|
||||
order.setInterco(interco);
|
||||
}
|
||||
return Beans.get(SaleOrderRepository.class).save(order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate project form SaleOrder and set bi-directional.
|
||||
*
|
||||
* @param saleOrder The order of origin.
|
||||
* @return The project generated.
|
||||
*/
|
||||
@Override
|
||||
public Project generateProject(SaleOrder saleOrder) {
|
||||
Project project = projectRepo.findByName(saleOrder.getFullName() + "_project");
|
||||
project =
|
||||
project == null
|
||||
? this.generateProject(
|
||||
null,
|
||||
saleOrder.getFullName() + "_project",
|
||||
saleOrder.getSalemanUser(),
|
||||
saleOrder.getCompany(),
|
||||
saleOrder.getClientPartner())
|
||||
: project;
|
||||
saleOrder.setProject(project);
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project generateProject(
|
||||
Project parentProject,
|
||||
String fullName,
|
||||
User assignedTo,
|
||||
Company company,
|
||||
Partner clientPartner) {
|
||||
Project project =
|
||||
super.generateProject(parentProject, fullName, assignedTo, company, clientPartner);
|
||||
if (assignedTo != null) {
|
||||
project.addMembersUserSetItem(assignedTo);
|
||||
}
|
||||
project.setImputable(true);
|
||||
if (parentProject != null && parentProject.getIsInvoicingTimesheet()) {
|
||||
project.setIsInvoicingTimesheet(true);
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project generatePhaseProject(SaleOrderLine saleOrderLine, Project parent) {
|
||||
Project project =
|
||||
generateProject(
|
||||
parent,
|
||||
saleOrderLine.getFullName(),
|
||||
saleOrderLine.getSaleOrder().getSalemanUser(),
|
||||
parent.getCompany(),
|
||||
parent.getClientPartner());
|
||||
project.setProjectTypeSelect(ProjectRepository.TYPE_PHASE);
|
||||
saleOrderLine.setProject(project);
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Project createProjectFromTemplate(
|
||||
ProjectTemplate projectTemplate, String projectCode, Partner clientPartner)
|
||||
throws AxelorException {
|
||||
|
||||
Project project = super.createProjectFromTemplate(projectTemplate, projectCode, clientPartner);
|
||||
|
||||
if (projectTemplate.getIsBusinessProject()) {
|
||||
project.setCurrency(clientPartner.getCurrency());
|
||||
if (clientPartner.getPartnerAddressList() != null
|
||||
&& !clientPartner.getPartnerAddressList().isEmpty()) {
|
||||
project.setCustomerAddress(
|
||||
clientPartner.getPartnerAddressList().iterator().next().getAddress());
|
||||
}
|
||||
if (clientPartner.getSalePartnerPriceList() != null
|
||||
&& clientPartner.getSalePartnerPriceList().getPriceListSet() != null
|
||||
&& !clientPartner.getSalePartnerPriceList().getPriceListSet().isEmpty()) {
|
||||
project.setPriceList(
|
||||
clientPartner.getSalePartnerPriceList().getPriceListSet().iterator().next());
|
||||
}
|
||||
project.setIsInvoicingExpenses(projectTemplate.getIsInvoicingExpenses());
|
||||
project.setIsInvoicingPurchases(projectTemplate.getIsInvoicingPurchases());
|
||||
project.setInvoicingComment(projectTemplate.getInvoicingComment());
|
||||
project.setIsBusinessProject(projectTemplate.getIsBusinessProject());
|
||||
}
|
||||
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamTask createTask(TaskTemplate taskTemplate, Project project) {
|
||||
TeamTask task = super.createTask(taskTemplate, project);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.base.service.DurationService;
|
||||
import com.axelor.apps.base.service.app.AppBaseService;
|
||||
import com.axelor.apps.contract.db.Contract;
|
||||
import com.axelor.apps.contract.db.repo.ConsumptionLineRepository;
|
||||
import com.axelor.apps.contract.db.repo.ContractLineRepository;
|
||||
import com.axelor.apps.contract.db.repo.ContractRepository;
|
||||
import com.axelor.apps.contract.service.ContractLineService;
|
||||
import com.axelor.apps.contract.service.ContractServiceImpl;
|
||||
import com.axelor.apps.contract.service.ContractVersionService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class ProjectContractServiceImpl extends ContractServiceImpl {
|
||||
|
||||
@Inject
|
||||
public ProjectContractServiceImpl(
|
||||
AppBaseService appBaseService,
|
||||
ContractVersionService versionService,
|
||||
ContractLineService contractLineService,
|
||||
DurationService durationService,
|
||||
ContractLineRepository contractLineRepo,
|
||||
ConsumptionLineRepository consumptionLineRepo,
|
||||
ContractRepository contractRepository) {
|
||||
super(
|
||||
appBaseService,
|
||||
versionService,
|
||||
contractLineService,
|
||||
durationService,
|
||||
contractLineRepo,
|
||||
consumptionLineRepo,
|
||||
contractRepository);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Invoice generateInvoice(Contract contract) throws AxelorException {
|
||||
Invoice invoice = super.generateInvoice(contract);
|
||||
Project project = contract.getProject();
|
||||
|
||||
if (project != null && project.getIsBusinessProject()) {
|
||||
invoice.setProject(project);
|
||||
}
|
||||
|
||||
return invoice;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.ProjectFolder;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ProjectFolderService {
|
||||
|
||||
String printProjectsPlanificationAndCost(ProjectFolder projectFolder)
|
||||
throws IOException, AxelorException;
|
||||
|
||||
String printProjectFinancialReport(ProjectFolder projectFolder)
|
||||
throws IOException, AxelorException;
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.ReportFactory;
|
||||
import com.axelor.apps.base.service.app.AppBaseService;
|
||||
import com.axelor.apps.businessproject.report.IReport;
|
||||
import com.axelor.apps.businessproject.report.ITranslation;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.ProjectFolder;
|
||||
import com.axelor.apps.report.engine.ReportSettings;
|
||||
import com.axelor.apps.tool.ModelTool;
|
||||
import com.axelor.apps.tool.ThrowConsumer;
|
||||
import com.axelor.apps.tool.file.PdfTool;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ProjectFolderServiceImpl implements ProjectFolderService {
|
||||
|
||||
@Override
|
||||
public String printProjectsPlanificationAndCost(ProjectFolder projectFolder)
|
||||
throws IOException, AxelorException {
|
||||
List<File> printedProjects = new ArrayList<>();
|
||||
List<Long> ids = new ArrayList<Long>();
|
||||
|
||||
for (Project project : projectFolder.getProjectSet()) {
|
||||
ids.add(project.getId());
|
||||
}
|
||||
ModelTool.apply(
|
||||
Project.class,
|
||||
ids,
|
||||
new ThrowConsumer<Project>() {
|
||||
@Override
|
||||
public void accept(Project project) throws Exception {
|
||||
String name = I18n.get(ITranslation.PROJECT_REPORT_TITLE_FOR_PLANIFICATION_AND_COST);
|
||||
if (project.getCode() != null) {
|
||||
name += " (" + project.getCode() + ")";
|
||||
}
|
||||
printedProjects.add(printCopiesToFile(project, name, IReport.PLANNIF_AND_COST));
|
||||
}
|
||||
});
|
||||
|
||||
String fileName =
|
||||
getProjectFilesName(I18n.get(ITranslation.PROJECT_REPORT_TITLE_FOR_PLANIFICATION_AND_COST));
|
||||
return PdfTool.mergePdfToFileLink(printedProjects, fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String printProjectFinancialReport(ProjectFolder projectFolder)
|
||||
throws IOException, AxelorException {
|
||||
List<File> printedProjects = new ArrayList<>();
|
||||
List<Long> ids = new ArrayList<Long>();
|
||||
|
||||
for (Project project : projectFolder.getProjectSet()) {
|
||||
ids.add(project.getId());
|
||||
}
|
||||
ModelTool.apply(
|
||||
Project.class,
|
||||
ids,
|
||||
new ThrowConsumer<Project>() {
|
||||
@Override
|
||||
public void accept(Project project) throws Exception {
|
||||
String name =
|
||||
I18n.get(ITranslation.PROJECT_REPORT_TITLE_FOR_FINANCIAL) + " " + project.getCode();
|
||||
printedProjects.add(printCopiesToFile(project, name, IReport.PROJECT));
|
||||
}
|
||||
});
|
||||
|
||||
String fileName =
|
||||
getProjectFilesName(I18n.get(ITranslation.PROJECT_REPORT_TITLE_FOR_FINANCIAL));
|
||||
return PdfTool.mergePdfToFileLink(printedProjects, fileName);
|
||||
}
|
||||
|
||||
public File printCopiesToFile(Project project, String name, String reportDesignName)
|
||||
throws AxelorException, IOException {
|
||||
File file = print(project, name, reportDesignName);
|
||||
return PdfTool.printCopiesToFile(file, 1);
|
||||
}
|
||||
|
||||
public File print(Project project, String name, String reportDesignName) throws AxelorException {
|
||||
ReportSettings reportSettings = prepareReportSettings(project, name, reportDesignName);
|
||||
return reportSettings.generate().getFile();
|
||||
}
|
||||
|
||||
private ReportSettings prepareReportSettings(
|
||||
Project project, String name, String reportDesignName) {
|
||||
|
||||
ReportSettings reportSetting = ReportFactory.createReport(reportDesignName, name);
|
||||
|
||||
return reportSetting
|
||||
.addParam("ProjectId", project.getId())
|
||||
.addParam("Locale", ReportSettings.getPrintingLocale(null))
|
||||
.addFormat(ReportSettings.FORMAT_PDF);
|
||||
}
|
||||
|
||||
protected String getProjectFilesName(String fileName) {
|
||||
return fileName
|
||||
+ " - "
|
||||
+ Beans.get(AppBaseService.class).getTodayDate().format(DateTimeFormatter.BASIC_ISO_DATE)
|
||||
+ "."
|
||||
+ ReportSettings.FORMAT_PDF;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.base.db.Partner;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderLineServiceSupplychainImpl;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderServiceSupplychainImpl;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderPurchaseServiceImpl;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
|
||||
public class ProjectPurchaseServiceImpl extends SaleOrderPurchaseServiceImpl {
|
||||
|
||||
@Inject
|
||||
public ProjectPurchaseServiceImpl(
|
||||
PurchaseOrderServiceSupplychainImpl purchaseOrderServiceSupplychainImpl,
|
||||
PurchaseOrderLineServiceSupplychainImpl purchaseOrderLineServiceSupplychainImpl) {
|
||||
super(purchaseOrderServiceSupplychainImpl, purchaseOrderLineServiceSupplychainImpl);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public PurchaseOrder createPurchaseOrder(
|
||||
Partner supplierPartner, List<SaleOrderLine> saleOrderLineList, SaleOrder saleOrder)
|
||||
throws AxelorException {
|
||||
PurchaseOrder purchaseOrder =
|
||||
super.createPurchaseOrder(supplierPartner, saleOrderLineList, saleOrder);
|
||||
|
||||
if (purchaseOrder != null && saleOrder != null) {
|
||||
purchaseOrder.setProject(saleOrder.getProject());
|
||||
}
|
||||
|
||||
return purchaseOrder;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.db.repo.InvoiceRepository;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrderLine;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
|
||||
import com.axelor.apps.stock.db.StockMoveLine;
|
||||
import com.axelor.apps.stock.db.repo.StockMoveLineRepository;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderInvoiceService;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderInvoiceService;
|
||||
import com.axelor.apps.supplychain.service.StockMoveInvoiceServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.StockMoveLineServiceSupplychain;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public class ProjectStockMoveInvoiceServiceImpl extends StockMoveInvoiceServiceImpl {
|
||||
|
||||
@Inject
|
||||
public ProjectStockMoveInvoiceServiceImpl(
|
||||
SaleOrderInvoiceService saleOrderInvoiceService,
|
||||
PurchaseOrderInvoiceService purchaseOrderInvoiceService,
|
||||
StockMoveLineServiceSupplychain stockMoveLineServiceSupplychain,
|
||||
InvoiceRepository invoiceRepository,
|
||||
SaleOrderRepository saleOrderRepo,
|
||||
PurchaseOrderRepository purchaseOrderRepo,
|
||||
StockMoveLineRepository stockMoveLineRepository) {
|
||||
super(
|
||||
saleOrderInvoiceService,
|
||||
purchaseOrderInvoiceService,
|
||||
stockMoveLineServiceSupplychain,
|
||||
invoiceRepository,
|
||||
saleOrderRepo,
|
||||
purchaseOrderRepo,
|
||||
stockMoveLineRepository);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> createInvoiceLine(
|
||||
Invoice invoice, StockMoveLine stockMoveLine, BigDecimal qty) throws AxelorException {
|
||||
|
||||
List<InvoiceLine> invoiceLines = super.createInvoiceLine(invoice, stockMoveLine, qty);
|
||||
for (InvoiceLine invoiceLine : invoiceLines) {
|
||||
SaleOrderLine saleOrderLine = invoiceLine.getSaleOrderLine();
|
||||
if (saleOrderLine != null) {
|
||||
invoiceLine.setProject(saleOrderLine.getProject());
|
||||
}
|
||||
|
||||
PurchaseOrderLine purchaseOrderLine = invoiceLine.getPurchaseOrderLine();
|
||||
if (purchaseOrderLine != null) {
|
||||
invoiceLine.setProject(purchaseOrderLine.getProject());
|
||||
}
|
||||
}
|
||||
|
||||
return invoiceLines;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator;
|
||||
import com.axelor.apps.base.db.PriceList;
|
||||
import com.axelor.apps.base.db.PriceListLine;
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.base.db.repo.AppBaseRepository;
|
||||
import com.axelor.apps.base.db.repo.PartnerRepository;
|
||||
import com.axelor.apps.base.db.repo.PriceListLineRepository;
|
||||
import com.axelor.apps.base.db.repo.PriceListRepository;
|
||||
import com.axelor.apps.base.service.PartnerPriceListService;
|
||||
import com.axelor.apps.base.service.PriceListService;
|
||||
import com.axelor.apps.businessproject.service.app.AppBusinessProjectService;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrderLine;
|
||||
import com.axelor.apps.purchase.service.PurchaseOrderLineServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderInvoiceServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.invoice.generator.InvoiceLineGeneratorSupplyChain;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.google.inject.Inject;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PurchaseOrderInvoiceProjectServiceImpl extends PurchaseOrderInvoiceServiceImpl {
|
||||
|
||||
@Inject private PriceListService priceListService;
|
||||
|
||||
@Inject private PurchaseOrderLineServiceImpl purchaseOrderLineServiceImpl;
|
||||
|
||||
@Inject protected AppBusinessProjectService appBusinessProjectService;
|
||||
|
||||
@Override
|
||||
protected void processPurchaseOrderLine(
|
||||
Invoice invoice, List<InvoiceLine> invoiceLineList, PurchaseOrderLine purchaseOrderLine)
|
||||
throws AxelorException {
|
||||
super.processPurchaseOrderLine(invoice, invoiceLineList, purchaseOrderLine);
|
||||
invoiceLineList.get(invoiceLineList.size() - 1).setProject(purchaseOrderLine.getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> createInvoiceLine(Invoice invoice, PurchaseOrderLine purchaseOrderLine)
|
||||
throws AxelorException {
|
||||
|
||||
Product product = purchaseOrderLine.getProduct();
|
||||
BigDecimal price = product.getCostPrice();
|
||||
BigDecimal discountAmount = product.getCostPrice();
|
||||
int discountTypeSelect = 1;
|
||||
if (invoice.getPartner().getChargeBackPurchaseSelect()
|
||||
== PartnerRepository.CHARGING_BACK_TYPE_PRICE_LIST) {
|
||||
PriceList priceList =
|
||||
Beans.get(PartnerPriceListService.class)
|
||||
.getDefaultPriceList(invoice.getPartner(), PriceListRepository.TYPE_SALE);
|
||||
if (priceList != null) {
|
||||
PriceListLine priceListLine =
|
||||
purchaseOrderLineServiceImpl.getPriceListLine(purchaseOrderLine, priceList, price);
|
||||
if (priceListLine != null) {
|
||||
discountTypeSelect = priceListLine.getTypeSelect();
|
||||
}
|
||||
if ((appBusinessProjectService.getAppBase().getComputeMethodDiscountSelect()
|
||||
== AppBaseRepository.INCLUDE_DISCOUNT_REPLACE_ONLY
|
||||
&& discountTypeSelect == PriceListLineRepository.TYPE_REPLACE)
|
||||
|| appBusinessProjectService.getAppBase().getComputeMethodDiscountSelect()
|
||||
== AppBaseRepository.INCLUDE_DISCOUNT) {
|
||||
Map<String, Object> discounts =
|
||||
priceListService.getDiscounts(priceList, priceListLine, price);
|
||||
if (discounts != null) {
|
||||
discountAmount = (BigDecimal) discounts.get("discountAmount");
|
||||
price =
|
||||
priceListService.computeDiscount(
|
||||
price, (int) discounts.get("discountTypeSelect"), discountAmount);
|
||||
}
|
||||
|
||||
} else {
|
||||
Map<String, Object> discounts =
|
||||
priceListService.getDiscounts(priceList, priceListLine, price);
|
||||
if (discounts != null) {
|
||||
discountAmount = (BigDecimal) discounts.get("discountAmount");
|
||||
if (discounts.get("price") != null) {
|
||||
price = (BigDecimal) discounts.get("price");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InvoiceLineGenerator invoiceLineGenerator =
|
||||
new InvoiceLineGenerator(
|
||||
invoice,
|
||||
product,
|
||||
product.getName(),
|
||||
price,
|
||||
price,
|
||||
price,
|
||||
purchaseOrderLine.getDescription(),
|
||||
purchaseOrderLine.getQty(),
|
||||
purchaseOrderLine.getUnit(),
|
||||
null,
|
||||
InvoiceLineGenerator.DEFAULT_SEQUENCE,
|
||||
discountAmount,
|
||||
discountTypeSelect,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
0) {
|
||||
@Override
|
||||
public List<InvoiceLine> creates() throws AxelorException {
|
||||
|
||||
InvoiceLine invoiceLine = this.createInvoiceLine();
|
||||
invoiceLine.setProject(purchaseOrderLine.getProject());
|
||||
|
||||
List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
|
||||
invoiceLines.add(invoiceLine);
|
||||
|
||||
return invoiceLines;
|
||||
}
|
||||
};
|
||||
return invoiceLineGenerator.creates();
|
||||
} else if (invoice.getPartner().getChargeBackPurchaseSelect()
|
||||
== PartnerRepository.CHARGING_BACK_TYPE_PERCENTAGE) {
|
||||
price =
|
||||
price
|
||||
.multiply(
|
||||
invoice
|
||||
.getPartner()
|
||||
.getChargeBackPurchase()
|
||||
.divide(
|
||||
new BigDecimal(100),
|
||||
appBusinessProjectService.getNbDecimalDigitForUnitPrice(),
|
||||
BigDecimal.ROUND_HALF_UP))
|
||||
.setScale(
|
||||
appBusinessProjectService.getNbDecimalDigitForUnitPrice(),
|
||||
BigDecimal.ROUND_HALF_UP);
|
||||
InvoiceLineGenerator invoiceLineGenerator =
|
||||
new InvoiceLineGenerator(
|
||||
invoice,
|
||||
product,
|
||||
product.getName(),
|
||||
price,
|
||||
price,
|
||||
price,
|
||||
purchaseOrderLine.getDescription(),
|
||||
purchaseOrderLine.getQty(),
|
||||
purchaseOrderLine.getUnit(),
|
||||
null,
|
||||
InvoiceLineGenerator.DEFAULT_SEQUENCE,
|
||||
discountAmount,
|
||||
discountTypeSelect,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
0) {
|
||||
@Override
|
||||
public List<InvoiceLine> creates() throws AxelorException {
|
||||
|
||||
InvoiceLine invoiceLine = this.createInvoiceLine();
|
||||
invoiceLine.setProject(purchaseOrderLine.getProject());
|
||||
|
||||
List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
|
||||
invoiceLines.add(invoiceLine);
|
||||
|
||||
return invoiceLines;
|
||||
}
|
||||
};
|
||||
return invoiceLineGenerator.creates();
|
||||
} else {
|
||||
InvoiceLineGeneratorSupplyChain invoiceLineGenerator =
|
||||
new InvoiceLineGeneratorSupplyChain(
|
||||
invoice,
|
||||
product,
|
||||
purchaseOrderLine.getProductName(),
|
||||
purchaseOrderLine.getDescription(),
|
||||
purchaseOrderLine.getQty(),
|
||||
purchaseOrderLine.getUnit(),
|
||||
purchaseOrderLine.getSequence(),
|
||||
false,
|
||||
null,
|
||||
purchaseOrderLine,
|
||||
null,
|
||||
false,
|
||||
0) {
|
||||
@Override
|
||||
public List<InvoiceLine> creates() throws AxelorException {
|
||||
|
||||
InvoiceLine invoiceLine = this.createInvoiceLine();
|
||||
invoiceLine.setProject(purchaseOrderLine.getProject());
|
||||
|
||||
List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
|
||||
invoiceLines.add(invoiceLine);
|
||||
|
||||
return invoiceLines;
|
||||
}
|
||||
};
|
||||
return invoiceLineGenerator.creates();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import java.util.List;
|
||||
|
||||
public interface PurchaseOrderLineProjectService {
|
||||
|
||||
public void setProject(List<Long> purchaseOrderLineIds, Project project);
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrder;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrderLine;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderLineServiceSupplychainImpl;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
|
||||
public class PurchaseOrderLineServiceProjectImpl extends PurchaseOrderLineServiceSupplychainImpl
|
||||
implements PurchaseOrderLineProjectService {
|
||||
|
||||
@Inject private PurchaseOrderLineRepository purchaseOrderLineRepo;
|
||||
|
||||
@Override
|
||||
public PurchaseOrderLine createPurchaseOrderLine(
|
||||
PurchaseOrder purchaseOrder, SaleOrderLine saleOrderLine) throws AxelorException {
|
||||
|
||||
PurchaseOrderLine line = super.createPurchaseOrderLine(purchaseOrder, saleOrderLine);
|
||||
|
||||
if (line != null && saleOrderLine != null) {
|
||||
line.setProject(saleOrderLine.getProject());
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void setProject(List<Long> purchaseOrderLineIds, Project project) {
|
||||
|
||||
if (purchaseOrderLineIds != null) {
|
||||
|
||||
List<PurchaseOrderLine> purchaseOrderLineList =
|
||||
purchaseOrderLineRepo.all().filter("self.id in ?1", purchaseOrderLineIds).fetch();
|
||||
|
||||
for (PurchaseOrderLine line : purchaseOrderLineList) {
|
||||
line.setProject(project);
|
||||
purchaseOrderLineRepo.save(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.db.PaymentCondition;
|
||||
import com.axelor.apps.account.db.PaymentMode;
|
||||
import com.axelor.apps.account.db.repo.InvoiceRepository;
|
||||
import com.axelor.apps.account.service.invoice.InvoiceService;
|
||||
import com.axelor.apps.base.db.Company;
|
||||
import com.axelor.apps.base.db.Currency;
|
||||
import com.axelor.apps.base.db.Partner;
|
||||
import com.axelor.apps.base.db.PriceList;
|
||||
import com.axelor.apps.businessproject.service.app.AppBusinessProjectService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
|
||||
import com.axelor.apps.sale.service.saleorder.SaleOrderLineService;
|
||||
import com.axelor.apps.sale.service.saleorder.SaleOrderWorkflowServiceImpl;
|
||||
import com.axelor.apps.stock.db.repo.StockMoveRepository;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderInvoiceServiceImpl;
|
||||
import com.axelor.apps.supplychain.service.app.AppSupplychainService;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public class SaleOrderInvoiceProjectServiceImpl extends SaleOrderInvoiceServiceImpl {
|
||||
|
||||
private AppBusinessProjectService appBusinessProjectService;
|
||||
|
||||
@Inject
|
||||
public SaleOrderInvoiceProjectServiceImpl(
|
||||
AppSupplychainService appSupplychainService,
|
||||
SaleOrderRepository saleOrderRepo,
|
||||
InvoiceRepository invoiceRepo,
|
||||
InvoiceService invoiceService,
|
||||
AppBusinessProjectService appBusinessProjectService,
|
||||
StockMoveRepository stockMoveRepository,
|
||||
SaleOrderLineService saleOrderLineService,
|
||||
SaleOrderWorkflowServiceImpl saleOrderWorkflowServiceImpl) {
|
||||
super(
|
||||
appSupplychainService,
|
||||
saleOrderRepo,
|
||||
invoiceRepo,
|
||||
invoiceService,
|
||||
saleOrderLineService,
|
||||
stockMoveRepository,
|
||||
saleOrderWorkflowServiceImpl);
|
||||
this.appBusinessProjectService = appBusinessProjectService;
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public Invoice mergeInvoice(
|
||||
List<Invoice> invoiceList,
|
||||
Company company,
|
||||
Currency currency,
|
||||
Partner partner,
|
||||
Partner contactPartner,
|
||||
PriceList priceList,
|
||||
PaymentMode paymentMode,
|
||||
PaymentCondition paymentCondition,
|
||||
SaleOrder saleOrder,
|
||||
Project project)
|
||||
throws AxelorException {
|
||||
Invoice invoiceMerged =
|
||||
super.mergeInvoice(
|
||||
invoiceList,
|
||||
company,
|
||||
currency,
|
||||
partner,
|
||||
contactPartner,
|
||||
priceList,
|
||||
paymentMode,
|
||||
paymentCondition,
|
||||
saleOrder);
|
||||
if (project != null
|
||||
&& !appBusinessProjectService.getAppBusinessProject().getProjectInvoiceLines()) {
|
||||
invoiceMerged.setProject(project);
|
||||
for (InvoiceLine invoiceLine : invoiceMerged.getInvoiceLineList()) {
|
||||
invoiceLine.setProject(project);
|
||||
}
|
||||
}
|
||||
return invoiceMerged;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> createInvoiceLine(
|
||||
Invoice invoice, SaleOrderLine saleOrderLine, BigDecimal qtyToInvoice)
|
||||
throws AxelorException {
|
||||
List<InvoiceLine> invoiceLines = super.createInvoiceLine(invoice, saleOrderLine, qtyToInvoice);
|
||||
for (InvoiceLine invoiceLine : invoiceLines) {
|
||||
if (saleOrderLine != null) {
|
||||
invoiceLine.setProject(saleOrderLine.getProject());
|
||||
}
|
||||
}
|
||||
return invoiceLines;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import java.util.List;
|
||||
|
||||
public interface SaleOrderLineProjectService {
|
||||
|
||||
public void setProject(List<Long> saleOrderLineIds, Project project);
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.AnalyticMoveLine;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderLineRepository;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderLineServiceSupplyChainImpl;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
|
||||
public class SaleOrderLineProjectServiceImpl extends SaleOrderLineServiceSupplyChainImpl
|
||||
implements SaleOrderLineProjectService {
|
||||
|
||||
@Inject private SaleOrderLineRepository saleOrderLineRepo;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void setProject(List<Long> saleOrderLineIds, Project project) {
|
||||
|
||||
if (saleOrderLineIds != null) {
|
||||
|
||||
List<SaleOrderLine> saleOrderLineList =
|
||||
saleOrderLineRepo.all().filter("self.id in ?1", saleOrderLineIds).fetch();
|
||||
|
||||
for (SaleOrderLine line : saleOrderLineList) {
|
||||
line.setProject(project);
|
||||
saleOrderLineRepo.save(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SaleOrderLine createAnalyticDistributionWithTemplate(SaleOrderLine saleOrderLine) {
|
||||
|
||||
SaleOrderLine soLine = super.createAnalyticDistributionWithTemplate(saleOrderLine);
|
||||
List<AnalyticMoveLine> analyticMoveLineList = soLine.getAnalyticMoveLineList();
|
||||
|
||||
if (soLine.getProject() != null && analyticMoveLineList != null) {
|
||||
analyticMoveLineList.forEach(analyticLine -> analyticLine.setProject(soLine.getProject()));
|
||||
}
|
||||
return soLine;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.base.db.AppBusinessProject;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.TaskTemplate;
|
||||
import com.axelor.apps.project.service.TeamTaskProjectService;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.auth.db.User;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public interface TeamTaskBusinessProjectService extends TeamTaskProjectService {
|
||||
|
||||
TeamTask create(SaleOrderLine saleOrderLine, Project project, User assignedTo);
|
||||
|
||||
TeamTask create(TaskTemplate template, Project project, LocalDateTime date, BigDecimal qty);
|
||||
|
||||
TeamTask updateDiscount(TeamTask teamTask);
|
||||
|
||||
TeamTask compute(TeamTask teamTask);
|
||||
|
||||
List<InvoiceLine> createInvoiceLines(Invoice invoice, List<TeamTask> teamTaskList, int priority)
|
||||
throws AxelorException;
|
||||
|
||||
List<InvoiceLine> createInvoiceLine(Invoice invoice, TeamTask teamTask, int priority)
|
||||
throws AxelorException;
|
||||
|
||||
TeamTask computeDefaultInformation(TeamTask teamTask);
|
||||
|
||||
@Transactional(rollbackOn = {AxelorException.class, Exception.class})
|
||||
TeamTask updateTask(TeamTask teamTask, AppBusinessProject appBusinessProject);
|
||||
|
||||
TeamTask resetTeamTaskValues(TeamTask teamTask);
|
||||
}
|
||||
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator;
|
||||
import com.axelor.apps.base.db.AppBusinessProject;
|
||||
import com.axelor.apps.base.db.PriceList;
|
||||
import com.axelor.apps.base.db.PriceListLine;
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.base.db.repo.PriceListLineRepository;
|
||||
import com.axelor.apps.base.db.repo.PriceListRepository;
|
||||
import com.axelor.apps.base.service.PartnerPriceListService;
|
||||
import com.axelor.apps.base.service.PriceListService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.TaskTemplate;
|
||||
import com.axelor.apps.project.db.TeamTaskCategory;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.project.service.TeamTaskProjectServiceImpl;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.service.app.AppSaleService;
|
||||
import com.axelor.auth.db.User;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TeamTaskBusinessProjectServiceImpl extends TeamTaskProjectServiceImpl
|
||||
implements TeamTaskBusinessProjectService {
|
||||
|
||||
private PriceListLineRepository priceListLineRepository;
|
||||
|
||||
private PriceListService priceListService;
|
||||
|
||||
@Inject
|
||||
public TeamTaskBusinessProjectServiceImpl(
|
||||
TeamTaskRepository teamTaskRepo,
|
||||
PriceListLineRepository priceListLineRepository,
|
||||
PriceListService priceListService) {
|
||||
super(teamTaskRepo);
|
||||
this.priceListLineRepository = priceListLineRepository;
|
||||
this.priceListService = priceListService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamTask create(SaleOrderLine saleOrderLine, Project project, User assignedTo) {
|
||||
TeamTask task = create(saleOrderLine.getFullName() + "_task", project, assignedTo);
|
||||
task.setProduct(saleOrderLine.getProduct());
|
||||
task.setUnit(saleOrderLine.getUnit());
|
||||
task.setCurrency(project.getClientPartner().getCurrency());
|
||||
if (project.getPriceList() != null) {
|
||||
PriceListLine line =
|
||||
priceListLineRepository.findByPriceListAndProduct(
|
||||
project.getPriceList(), saleOrderLine.getProduct());
|
||||
if (line != null) {
|
||||
task.setUnitPrice(line.getAmount());
|
||||
}
|
||||
}
|
||||
if (task.getUnitPrice() == null) {
|
||||
task.setUnitPrice(saleOrderLine.getProduct().getSalePrice());
|
||||
}
|
||||
task.setQuantity(saleOrderLine.getQty());
|
||||
task.setSaleOrderLine(saleOrderLine);
|
||||
task.setToInvoice(
|
||||
saleOrderLine.getSaleOrder() != null
|
||||
? saleOrderLine.getSaleOrder().getToInvoiceViaTask()
|
||||
: false);
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamTask create(
|
||||
TaskTemplate template, Project project, LocalDateTime date, BigDecimal qty) {
|
||||
TeamTask task = create(template.getName(), project, template.getAssignedTo());
|
||||
|
||||
task.setTaskDate(date.toLocalDate());
|
||||
task.setTaskEndDate(date.plusHours(template.getDuration().longValue()).toLocalDate());
|
||||
|
||||
BigDecimal plannedHrs = template.getTotalPlannedHrs();
|
||||
if (template.getIsUniqueTaskForMultipleQuantity() && qty.compareTo(BigDecimal.ONE) > 0) {
|
||||
plannedHrs = plannedHrs.multiply(qty);
|
||||
task.setName(task.getName() + " x" + qty.intValue());
|
||||
}
|
||||
task.setTotalPlannedHrs(plannedHrs);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamTask updateDiscount(TeamTask teamTask) {
|
||||
PriceList priceList = teamTask.getProject().getPriceList();
|
||||
if (priceList == null) {
|
||||
this.emptyDiscounts(teamTask);
|
||||
return teamTask;
|
||||
}
|
||||
|
||||
PriceListLine priceListLine =
|
||||
this.getPriceListLine(teamTask, priceList, teamTask.getUnitPrice());
|
||||
Map<String, Object> discounts =
|
||||
priceListService.getReplacedPriceAndDiscounts(
|
||||
priceList, priceListLine, teamTask.getUnitPrice());
|
||||
|
||||
if (discounts == null) {
|
||||
this.emptyDiscounts(teamTask);
|
||||
} else {
|
||||
teamTask.setDiscountTypeSelect((Integer) discounts.get("discountTypeSelect"));
|
||||
teamTask.setDiscountAmount((BigDecimal) discounts.get("discountAmount"));
|
||||
if (discounts.get("price") != null) {
|
||||
teamTask.setPriceDiscounted((BigDecimal) discounts.get("price"));
|
||||
}
|
||||
}
|
||||
return teamTask;
|
||||
}
|
||||
|
||||
private void emptyDiscounts(TeamTask teamTask) {
|
||||
teamTask.setDiscountTypeSelect(PriceListLineRepository.AMOUNT_TYPE_NONE);
|
||||
teamTask.setDiscountAmount(BigDecimal.ZERO);
|
||||
teamTask.setPriceDiscounted(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private PriceListLine getPriceListLine(TeamTask teamTask, PriceList priceList, BigDecimal price) {
|
||||
|
||||
return priceListService.getPriceListLine(
|
||||
teamTask.getProduct(), teamTask.getQuantity(), priceList, price);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamTask compute(TeamTask teamTask) {
|
||||
if (teamTask.getProduct() == null && teamTask.getProject() == null
|
||||
|| teamTask.getUnitPrice() == null
|
||||
|| teamTask.getQuantity() == null) {
|
||||
return teamTask;
|
||||
}
|
||||
BigDecimal priceDiscounted = this.computeDiscount(teamTask);
|
||||
BigDecimal exTaxTotal = this.computeAmount(teamTask.getQuantity(), priceDiscounted);
|
||||
|
||||
teamTask.setPriceDiscounted(priceDiscounted);
|
||||
teamTask.setExTaxTotal(exTaxTotal);
|
||||
|
||||
return teamTask;
|
||||
}
|
||||
|
||||
private BigDecimal computeDiscount(TeamTask teamTask) {
|
||||
|
||||
return priceListService.computeDiscount(
|
||||
teamTask.getUnitPrice(), teamTask.getDiscountTypeSelect(), teamTask.getDiscountAmount());
|
||||
}
|
||||
|
||||
private BigDecimal computeAmount(BigDecimal quantity, BigDecimal price) {
|
||||
|
||||
BigDecimal amount =
|
||||
price
|
||||
.multiply(quantity)
|
||||
.setScale(AppSaleService.DEFAULT_NB_DECIMAL_DIGITS, RoundingMode.HALF_EVEN);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> createInvoiceLines(
|
||||
Invoice invoice, List<TeamTask> teamTaskList, int priority) throws AxelorException {
|
||||
|
||||
List<InvoiceLine> invoiceLineList = new ArrayList<>();
|
||||
int count = 0;
|
||||
for (TeamTask teamTask : teamTaskList) {
|
||||
invoiceLineList.addAll(this.createInvoiceLine(invoice, teamTask, priority * 100 + count));
|
||||
count++;
|
||||
}
|
||||
return invoiceLineList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> createInvoiceLine(Invoice invoice, TeamTask teamTask, int priority)
|
||||
throws AxelorException {
|
||||
|
||||
InvoiceLineGenerator invoiceLineGenerator =
|
||||
new InvoiceLineGenerator(
|
||||
invoice,
|
||||
teamTask.getProduct(),
|
||||
teamTask.getName(),
|
||||
teamTask.getUnitPrice(),
|
||||
BigDecimal.ZERO,
|
||||
teamTask.getPriceDiscounted(),
|
||||
teamTask.getDescription(),
|
||||
teamTask.getQuantity(),
|
||||
teamTask.getUnit(),
|
||||
null,
|
||||
priority,
|
||||
teamTask.getDiscountAmount(),
|
||||
teamTask.getDiscountTypeSelect(),
|
||||
teamTask.getExTaxTotal(),
|
||||
BigDecimal.ZERO,
|
||||
false,
|
||||
false,
|
||||
0) {
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> creates() throws AxelorException {
|
||||
|
||||
InvoiceLine invoiceLine = this.createInvoiceLine();
|
||||
invoiceLine.setProject(teamTask.getProject());
|
||||
invoiceLine.setSaleOrderLine(teamTask.getSaleOrderLine());
|
||||
teamTask.setInvoiceLine(invoiceLine);
|
||||
|
||||
List<InvoiceLine> invoiceLines = new ArrayList<InvoiceLine>();
|
||||
invoiceLines.add(invoiceLine);
|
||||
|
||||
return invoiceLines;
|
||||
}
|
||||
};
|
||||
|
||||
return invoiceLineGenerator.creates();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setModuleFields(TeamTask teamTask, LocalDate date, TeamTask newTeamTask) {
|
||||
super.setModuleFields(teamTask, date, newTeamTask);
|
||||
|
||||
// Module 'business project' fields
|
||||
// none
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateModuleFields(TeamTask teamTask, TeamTask nextTeamTask) {
|
||||
super.updateModuleFields(teamTask, nextTeamTask);
|
||||
|
||||
// Module 'business project' fields
|
||||
nextTeamTask.setToInvoice(teamTask.getToInvoice());
|
||||
nextTeamTask.setExTaxTotal(teamTask.getExTaxTotal());
|
||||
nextTeamTask.setDiscountTypeSelect(teamTask.getDiscountTypeSelect());
|
||||
nextTeamTask.setDiscountAmount(teamTask.getDiscountAmount());
|
||||
nextTeamTask.setPriceDiscounted(teamTask.getPriceDiscounted());
|
||||
nextTeamTask.setInvoicingType(teamTask.getInvoicingType());
|
||||
nextTeamTask.setCustomerReferral(teamTask.getCustomerReferral());
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {AxelorException.class, Exception.class})
|
||||
@Override
|
||||
public TeamTask updateTask(TeamTask teamTask, AppBusinessProject appBusinessProject) {
|
||||
|
||||
teamTask = computeDefaultInformation(teamTask);
|
||||
|
||||
if (teamTask.getInvoicingType() == TeamTaskRepository.INVOICING_TYPE_PACKAGE) {
|
||||
switch (teamTask.getProject().getInvoicingSequenceSelect()) {
|
||||
case ProjectRepository.INVOICING_SEQ_INVOICE_PRE_TASK:
|
||||
teamTask.setToInvoice(
|
||||
appBusinessProject.getPreTaskStatusSet() != null
|
||||
&& appBusinessProject.getPreTaskStatusSet().contains(teamTask.getStatus()));
|
||||
break;
|
||||
|
||||
case ProjectRepository.INVOICING_SEQ_INVOICE_POST_TASK:
|
||||
teamTask.setToInvoice(
|
||||
appBusinessProject.getPostTaskStatusSet() != null
|
||||
&& appBusinessProject.getPostTaskStatusSet().contains(teamTask.getStatus()));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
teamTask.setToInvoice(
|
||||
teamTask.getInvoicingType() == TeamTaskRepository.INVOICING_TYPE_TIME_SPENT);
|
||||
}
|
||||
|
||||
return teamTaskRepo.save(teamTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamTask computeDefaultInformation(TeamTask teamTask) {
|
||||
|
||||
Product product = teamTask.getProduct();
|
||||
if (product != null) {
|
||||
teamTask.setInvoicingType(TeamTaskRepository.INVOICING_TYPE_PACKAGE);
|
||||
if (teamTask.getUnitPrice() == null
|
||||
|| teamTask.getUnitPrice().compareTo(BigDecimal.ZERO) == 0) {
|
||||
teamTask.setUnitPrice(this.computeUnitPrice(teamTask));
|
||||
}
|
||||
} else {
|
||||
TeamTaskCategory teamTaskCategory = teamTask.getTeamTaskCategory();
|
||||
if (teamTaskCategory == null) {
|
||||
return teamTask;
|
||||
}
|
||||
|
||||
teamTask.setInvoicingType(teamTaskCategory.getDefaultInvoicingType());
|
||||
teamTask.setProduct(teamTaskCategory.getDefaultProduct());
|
||||
product = teamTask.getProduct();
|
||||
if (product == null) {
|
||||
return teamTask;
|
||||
}
|
||||
teamTask.setUnitPrice(this.computeUnitPrice(teamTask));
|
||||
}
|
||||
teamTask.setUnit(product.getSalesUnit() == null ? product.getUnit() : product.getSalesUnit());
|
||||
teamTask.setCurrency(product.getSaleCurrency());
|
||||
teamTask.setQuantity(teamTask.getBudgetedTime());
|
||||
|
||||
teamTask = this.updateDiscount(teamTask);
|
||||
teamTask = this.compute(teamTask);
|
||||
return teamTask;
|
||||
}
|
||||
|
||||
private BigDecimal computeUnitPrice(TeamTask teamTask) {
|
||||
Product product = teamTask.getProduct();
|
||||
BigDecimal unitPrice = product.getSalePrice();
|
||||
|
||||
PriceList priceList =
|
||||
Beans.get(PartnerPriceListService.class)
|
||||
.getDefaultPriceList(
|
||||
teamTask.getProject().getClientPartner(), PriceListRepository.TYPE_SALE);
|
||||
if (priceList == null) {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
PriceListLine priceListLine = this.getPriceListLine(teamTask, priceList, unitPrice);
|
||||
Map<String, Object> discounts =
|
||||
priceListService.getReplacedPriceAndDiscounts(priceList, priceListLine, unitPrice);
|
||||
|
||||
if (discounts == null) {
|
||||
return unitPrice;
|
||||
} else {
|
||||
unitPrice =
|
||||
priceListService.computeDiscount(
|
||||
unitPrice,
|
||||
(Integer) discounts.get("discountTypeSelect"),
|
||||
(BigDecimal) discounts.get("discountAmount"));
|
||||
}
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamTask resetTeamTaskValues(TeamTask teamTask) {
|
||||
teamTask.setProduct(null);
|
||||
teamTask.setInvoicingType(null);
|
||||
teamTask.setToInvoice(null);
|
||||
teamTask.setQuantity(null);
|
||||
teamTask.setUnit(null);
|
||||
teamTask.setUnitPrice(null);
|
||||
teamTask.setCurrency(null);
|
||||
teamTask.setExTaxTotal(null);
|
||||
return teamTask;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.persist.Transactional;
|
||||
|
||||
public interface TimesheetLineBusinessService {
|
||||
|
||||
TimesheetLine getDefaultToInvoice(TimesheetLine timesheetLine);
|
||||
|
||||
@Transactional(rollbackOn = {AxelorException.class, Exception.class})
|
||||
public TimesheetLine updateTimesheetLines(TimesheetLine timesheetLine);
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.hr.db.Timesheet;
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.apps.hr.db.repo.TimesheetLineRepository;
|
||||
import com.axelor.apps.hr.service.timesheet.TimesheetLineServiceImpl;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.auth.db.User;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class TimesheetLineProjectServiceImpl extends TimesheetLineServiceImpl
|
||||
implements TimesheetLineBusinessService {
|
||||
|
||||
@Inject private ProjectRepository projectRepo;
|
||||
@Inject private TeamTaskRepository teamTaskaRepo;
|
||||
@Inject private TimesheetLineRepository timesheetLineRepo;
|
||||
|
||||
@Override
|
||||
public TimesheetLine createTimesheetLine(
|
||||
Project project,
|
||||
Product product,
|
||||
User user,
|
||||
LocalDate date,
|
||||
Timesheet timesheet,
|
||||
BigDecimal hours,
|
||||
String comments) {
|
||||
TimesheetLine timesheetLine =
|
||||
super.createTimesheetLine(project, product, user, date, timesheet, hours, comments);
|
||||
|
||||
if (project != null
|
||||
&& (project.getIsInvoicingTimesheet()
|
||||
|| (project.getParentProject() != null
|
||||
&& project.getParentProject().getIsInvoicingTimesheet())))
|
||||
timesheetLine.setToInvoice(true);
|
||||
|
||||
return timesheetLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimesheetLine getDefaultToInvoice(TimesheetLine timesheetLine) {
|
||||
Project project =
|
||||
timesheetLine.getProject() != null
|
||||
? projectRepo.find(timesheetLine.getProject().getId())
|
||||
: null;
|
||||
TeamTask teamTask =
|
||||
timesheetLine.getTeamTask() != null
|
||||
? teamTaskaRepo.find(timesheetLine.getTeamTask().getId())
|
||||
: null;
|
||||
|
||||
Boolean toInvoice = false;
|
||||
if (teamTask != null) {
|
||||
toInvoice = teamTask.getInvoicingType() == TeamTaskRepository.INVOICING_TYPE_TIME_SPENT;
|
||||
} else if (project != null) {
|
||||
toInvoice = project.getIsInvoicingTimesheet();
|
||||
}
|
||||
timesheetLine.setToInvoice(toInvoice);
|
||||
return timesheetLine;
|
||||
}
|
||||
|
||||
@Transactional(rollbackOn = {AxelorException.class, Exception.class})
|
||||
@Override
|
||||
public TimesheetLine updateTimesheetLines(TimesheetLine timesheetLine) {
|
||||
timesheetLine = getDefaultToInvoice(timesheetLine);
|
||||
return timesheetLineRepo.save(timesheetLine);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public interface TimesheetProjectService {
|
||||
|
||||
public BigDecimal computeDurationForCustomer(TimesheetLine timesheetLine) throws AxelorException;
|
||||
}
|
||||
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.base.db.PriceList;
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.base.service.PriceListService;
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.apps.hr.service.app.AppHumanResourceService;
|
||||
import com.axelor.apps.hr.service.config.HRConfigService;
|
||||
import com.axelor.apps.hr.service.timesheet.TimesheetLineService;
|
||||
import com.axelor.apps.hr.service.timesheet.TimesheetServiceImpl;
|
||||
import com.axelor.apps.hr.service.user.UserHrService;
|
||||
import com.axelor.apps.message.service.TemplateMessageService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectPlanningTimeRepository;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.auth.db.User;
|
||||
import com.axelor.auth.db.repo.UserRepository;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class TimesheetProjectServiceImpl extends TimesheetServiceImpl
|
||||
implements TimesheetProjectService {
|
||||
|
||||
@Inject
|
||||
public TimesheetProjectServiceImpl(
|
||||
PriceListService priceListService,
|
||||
AppHumanResourceService appHumanResourceService,
|
||||
HRConfigService hrConfigService,
|
||||
TemplateMessageService templateMessageService,
|
||||
ProjectRepository projectRepo,
|
||||
UserRepository userRepo,
|
||||
UserHrService userHrService,
|
||||
TimesheetLineService timesheetLineService,
|
||||
ProjectPlanningTimeRepository projectPlanningTimeRepository,
|
||||
TeamTaskRepository teamTaskRepository) {
|
||||
super(
|
||||
priceListService,
|
||||
appHumanResourceService,
|
||||
hrConfigService,
|
||||
templateMessageService,
|
||||
projectRepo,
|
||||
userRepo,
|
||||
userHrService,
|
||||
timesheetLineService,
|
||||
projectPlanningTimeRepository,
|
||||
teamTaskRepository);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InvoiceLine> createInvoiceLines(
|
||||
Invoice invoice, List<TimesheetLine> timesheetLineList, int priority) throws AxelorException {
|
||||
|
||||
List<InvoiceLine> invoiceLineList = new ArrayList<InvoiceLine>();
|
||||
int count = 0;
|
||||
DateTimeFormatter ddmmFormat = DateTimeFormatter.ofPattern("dd/MM");
|
||||
HashMap<String, Object[]> timeSheetInformationsMap = new HashMap<String, Object[]>();
|
||||
// Check if a consolidation by product and user must be done
|
||||
boolean consolidate = appHumanResourceService.getAppTimesheet().getConsolidateTSLine();
|
||||
|
||||
for (TimesheetLine timesheetLine : timesheetLineList) {
|
||||
Object[] tabInformations = new Object[6];
|
||||
tabInformations[0] = timesheetLine.getProduct();
|
||||
tabInformations[1] = timesheetLine.getUser();
|
||||
// Start date
|
||||
tabInformations[2] = timesheetLine.getDate();
|
||||
// End date, useful only for consolidation
|
||||
tabInformations[3] = timesheetLine.getDate();
|
||||
tabInformations[4] =
|
||||
timesheetLine.getDurationForCustomer().compareTo(BigDecimal.ZERO) != 0
|
||||
? this.computeDurationForCustomer(timesheetLine)
|
||||
: timesheetLine.getHoursDuration();
|
||||
tabInformations[5] = timesheetLine.getProject();
|
||||
|
||||
String key = null;
|
||||
if (consolidate) {
|
||||
key =
|
||||
timesheetLine.getProduct().getId()
|
||||
+ "|"
|
||||
+ timesheetLine.getUser().getId()
|
||||
+ "|"
|
||||
+ timesheetLine.getProject().getId();
|
||||
if (timeSheetInformationsMap.containsKey(key)) {
|
||||
tabInformations = timeSheetInformationsMap.get(key);
|
||||
// Update date
|
||||
if (timesheetLine.getDate().compareTo((LocalDate) tabInformations[2]) < 0) {
|
||||
// If date is lower than start date then replace start date by this one
|
||||
tabInformations[2] = timesheetLine.getDate();
|
||||
} else if (timesheetLine.getDate().compareTo((LocalDate) tabInformations[3]) > 0) {
|
||||
// If date is upper than end date then replace end date by this one
|
||||
tabInformations[3] = timesheetLine.getDate();
|
||||
}
|
||||
tabInformations[4] =
|
||||
((BigDecimal) tabInformations[4])
|
||||
.add(
|
||||
timesheetLine.getDurationForCustomer().compareTo(BigDecimal.ZERO) != 0
|
||||
? this.computeDurationForCustomer(timesheetLine)
|
||||
: timesheetLine.getHoursDuration());
|
||||
} else {
|
||||
timeSheetInformationsMap.put(key, tabInformations);
|
||||
}
|
||||
} else {
|
||||
key = String.valueOf(timesheetLine.getId());
|
||||
timeSheetInformationsMap.put(key, tabInformations);
|
||||
}
|
||||
}
|
||||
|
||||
for (Object[] timesheetInformations : timeSheetInformationsMap.values()) {
|
||||
|
||||
String strDate = null;
|
||||
Product product = (Product) timesheetInformations[0];
|
||||
User user = (User) timesheetInformations[1];
|
||||
LocalDate startDate = (LocalDate) timesheetInformations[2];
|
||||
LocalDate endDate = (LocalDate) timesheetInformations[3];
|
||||
BigDecimal hoursDuration = (BigDecimal) timesheetInformations[4];
|
||||
Project project = (Project) timesheetInformations[5];
|
||||
PriceList priceList = project.getPriceList();
|
||||
if (consolidate) {
|
||||
if (startDate != null && endDate != null) {
|
||||
strDate = startDate.format(ddmmFormat) + " - " + endDate.format(ddmmFormat);
|
||||
}
|
||||
} else {
|
||||
if (startDate != null) {
|
||||
strDate = startDate.format(ddmmFormat);
|
||||
}
|
||||
}
|
||||
|
||||
invoiceLineList.addAll(
|
||||
this.createInvoiceLine(
|
||||
invoice, product, user, strDate, hoursDuration, priority * 100 + count, priceList));
|
||||
invoiceLineList.get(invoiceLineList.size() - 1).setProject(project);
|
||||
count++;
|
||||
}
|
||||
|
||||
return invoiceLineList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal computeDurationForCustomer(TimesheetLine timesheetLine) throws AxelorException {
|
||||
return timesheetLineService.computeHoursDuration(
|
||||
timesheetLine.getTimesheet(), timesheetLine.getDurationForCustomer(), true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectRepository;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderInvoiceService;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderInvoiceService;
|
||||
import com.axelor.apps.supplychain.service.workflow.WorkflowCancelServiceSupplychainImpl;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
|
||||
public class WorkflowCancelServiceProjectImpl extends WorkflowCancelServiceSupplychainImpl {
|
||||
|
||||
@Inject InvoicingProjectRepository invoicingProjectRepo;
|
||||
|
||||
@Inject
|
||||
public WorkflowCancelServiceProjectImpl(
|
||||
SaleOrderInvoiceService saleOrderInvoiceService,
|
||||
PurchaseOrderInvoiceService purchaseOrderInvoiceService,
|
||||
SaleOrderRepository saleOrderRepository,
|
||||
PurchaseOrderRepository purchaseOrderRepository) {
|
||||
super(
|
||||
saleOrderInvoiceService,
|
||||
purchaseOrderInvoiceService,
|
||||
saleOrderRepository,
|
||||
purchaseOrderRepository);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public void afterCancel(Invoice invoice) throws AxelorException {
|
||||
super.afterCancel(invoice);
|
||||
|
||||
InvoicingProject invoicingProject =
|
||||
invoicingProjectRepo.all().filter("self.invoice = ?", invoice.getId()).fetchOne();
|
||||
|
||||
if (invoicingProject != null) {
|
||||
invoicingProject.setStatusSelect(InvoicingProjectRepository.STATUS_CANCELED);
|
||||
invoicingProjectRepo.save(invoicingProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectRepository;
|
||||
import com.axelor.apps.supplychain.service.IntercoService;
|
||||
import com.axelor.apps.supplychain.service.workflow.WorkflowValidationServiceSupplychainImpl;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
|
||||
public class WorkflowValidationServiceProjectImpl extends WorkflowValidationServiceSupplychainImpl {
|
||||
|
||||
@Inject InvoicingProjectRepository invoicingProjectRepo;
|
||||
|
||||
@Inject
|
||||
public WorkflowValidationServiceProjectImpl(IntercoService intercoService) {
|
||||
super(intercoService);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public void afterValidation(Invoice invoice) throws AxelorException {
|
||||
super.afterValidation(invoice);
|
||||
|
||||
InvoicingProject invoicingProject =
|
||||
invoicingProjectRepo.all().filter("self.invoice = ?", invoice.getId()).fetchOne();
|
||||
|
||||
if (invoicingProject != null) {
|
||||
invoicingProject.setStatusSelect(InvoicingProjectRepository.STATUS_VALIDATED);
|
||||
invoicingProjectRepo.save(invoicingProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.repo.InvoicePaymentRepository;
|
||||
import com.axelor.apps.account.service.config.AccountConfigService;
|
||||
import com.axelor.apps.account.service.payment.invoice.payment.InvoicePaymentCreateService;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectRepository;
|
||||
import com.axelor.apps.hr.db.ExpenseLine;
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.apps.hr.db.repo.TimesheetLineRepository;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrderLine;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
|
||||
import com.axelor.apps.supplychain.service.AccountingSituationSupplychainService;
|
||||
import com.axelor.apps.supplychain.service.PurchaseOrderInvoiceService;
|
||||
import com.axelor.apps.supplychain.service.SaleOrderInvoiceService;
|
||||
import com.axelor.apps.supplychain.service.app.AppSupplychainService;
|
||||
import com.axelor.apps.supplychain.service.workflow.WorkflowVentilationServiceSupplychainImpl;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
|
||||
public class WorkflowVentilationProjectServiceImpl
|
||||
extends WorkflowVentilationServiceSupplychainImpl {
|
||||
|
||||
private InvoicingProjectRepository invoicingProjectRepo;
|
||||
|
||||
private TimesheetLineRepository timesheetLineRepo;
|
||||
|
||||
@Inject
|
||||
public WorkflowVentilationProjectServiceImpl(
|
||||
AccountConfigService accountConfigService,
|
||||
InvoicePaymentRepository invoicePaymentRepo,
|
||||
InvoicePaymentCreateService invoicePaymentCreateService,
|
||||
SaleOrderInvoiceService saleOrderInvoiceService,
|
||||
PurchaseOrderInvoiceService purchaseOrderInvoiceService,
|
||||
SaleOrderRepository saleOrderRepository,
|
||||
PurchaseOrderRepository purchaseOrderRepository,
|
||||
AccountingSituationSupplychainService accountingSituationSupplychainService,
|
||||
AppSupplychainService appSupplychainService,
|
||||
InvoicingProjectRepository invoicingProjectRepo,
|
||||
TimesheetLineRepository timesheetLineRepo) {
|
||||
super(
|
||||
accountConfigService,
|
||||
invoicePaymentRepo,
|
||||
invoicePaymentCreateService,
|
||||
saleOrderInvoiceService,
|
||||
purchaseOrderInvoiceService,
|
||||
saleOrderRepository,
|
||||
purchaseOrderRepository,
|
||||
accountingSituationSupplychainService,
|
||||
appSupplychainService);
|
||||
this.invoicingProjectRepo = invoicingProjectRepo;
|
||||
this.timesheetLineRepo = timesheetLineRepo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public void afterVentilation(Invoice invoice) throws AxelorException {
|
||||
super.afterVentilation(invoice);
|
||||
InvoicingProject invoicingProject =
|
||||
invoicingProjectRepo.all().filter("self.invoice.id = ?", invoice.getId()).fetchOne();
|
||||
|
||||
if (invoicingProject != null) {
|
||||
for (SaleOrderLine saleOrderLine : invoicingProject.getSaleOrderLineSet()) {
|
||||
saleOrderLine.setInvoiced(true);
|
||||
}
|
||||
for (PurchaseOrderLine purchaseOrderLine : invoicingProject.getPurchaseOrderLineSet()) {
|
||||
purchaseOrderLine.setInvoiced(true);
|
||||
}
|
||||
for (TimesheetLine timesheetLine : invoicingProject.getLogTimesSet()) {
|
||||
timesheetLine.setInvoiced(true);
|
||||
|
||||
if (timesheetLine.getTeamTask() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
timesheetLine
|
||||
.getTeamTask()
|
||||
.setInvoiced(this.checkInvoicedTimesheetLines(timesheetLine.getTeamTask()));
|
||||
}
|
||||
for (ExpenseLine expenseLine : invoicingProject.getExpenseLineSet()) {
|
||||
expenseLine.setInvoiced(true);
|
||||
}
|
||||
for (TeamTask teamTask : invoicingProject.getTeamTaskSet()) {
|
||||
teamTask.setInvoiced(true);
|
||||
}
|
||||
for (Project project : invoicingProject.getProjectSet()) {
|
||||
project.setInvoiced(true);
|
||||
}
|
||||
|
||||
invoicingProject.setStatusSelect(InvoicingProjectRepository.STATUS_VENTILATED);
|
||||
invoicingProjectRepo.save(invoicingProject);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkInvoicedTimesheetLines(TeamTask teamTask) {
|
||||
|
||||
long timesheetLineCnt =
|
||||
timesheetLineRepo
|
||||
.all()
|
||||
.filter("self.teamTask.id = ?1 AND self.invoiced = ?2", teamTask.getId(), false)
|
||||
.count();
|
||||
|
||||
return timesheetLineCnt == 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.app;
|
||||
|
||||
import com.axelor.apps.base.db.AppBusinessProject;
|
||||
import com.axelor.apps.base.service.app.AppBaseService;
|
||||
|
||||
public interface AppBusinessProjectService extends AppBaseService {
|
||||
|
||||
public AppBusinessProject getAppBusinessProject();
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.app;
|
||||
|
||||
import com.axelor.apps.base.db.AppBusinessProject;
|
||||
import com.axelor.apps.base.db.repo.AppBusinessProjectRepository;
|
||||
import com.axelor.apps.base.service.app.AppBaseServiceImpl;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class AppBusinessProjectServiceImpl extends AppBaseServiceImpl
|
||||
implements AppBusinessProjectService {
|
||||
|
||||
@Inject private AppBusinessProjectRepository appBusinessProjectRepo;
|
||||
|
||||
@Override
|
||||
public AppBusinessProject getAppBusinessProject() {
|
||||
return appBusinessProjectRepo.all().fetchOne();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.batch;
|
||||
|
||||
import com.axelor.apps.base.service.administration.AbstractBatch;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.InvoicingProjectService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.exception.db.repo.ExceptionOriginRepository;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BatchInvoicingProjectService extends AbstractBatch {
|
||||
|
||||
protected ProjectRepository projectRepo;
|
||||
|
||||
protected InvoicingProjectService invoicingProjectService;
|
||||
|
||||
@Inject
|
||||
public BatchInvoicingProjectService(
|
||||
ProjectRepository projectRepo, InvoicingProjectService invoicingProjectService) {
|
||||
this.projectRepo = projectRepo;
|
||||
this.invoicingProjectService = invoicingProjectService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
|
||||
Map<String, Object> contextValues = null;
|
||||
try {
|
||||
contextValues = ProjectInvoicingAssistantBatchService.createJsonContext(batch);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
|
||||
List<Object> generatedInvoicingProjectList = new ArrayList<Object>();
|
||||
|
||||
List<Project> projectList =
|
||||
projectRepo
|
||||
.all()
|
||||
.filter(
|
||||
"self.toInvoice = ?1 AND self.statusSelect NOT IN (?2)",
|
||||
true,
|
||||
ProjectRepository.STATE_CANCELED,
|
||||
ProjectRepository.STATE_FINISHED)
|
||||
.fetch();
|
||||
|
||||
for (Project project : projectList) {
|
||||
try {
|
||||
InvoicingProject invoicingProject =
|
||||
invoicingProjectService.generateInvoicingProject(project);
|
||||
|
||||
if (invoicingProject != null && invoicingProject.getId() != null) {
|
||||
incrementDone();
|
||||
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("id", invoicingProject.getId());
|
||||
generatedInvoicingProjectList.add(map);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
incrementAnomaly();
|
||||
TraceBackService.trace(
|
||||
new Exception(
|
||||
String.format(
|
||||
I18n.get(IExceptionMessage.BATCH_INVOICING_PROJECT_1), project.getId()),
|
||||
e),
|
||||
ExceptionOriginRepository.INVOICE_ORIGIN,
|
||||
batch.getId());
|
||||
}
|
||||
}
|
||||
ProjectInvoicingAssistantBatchService.updateJsonObject(
|
||||
batch, generatedInvoicingProjectList, "generatedInvoicingProjectSet", contextValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stop() {
|
||||
|
||||
String comment =
|
||||
String.format(
|
||||
"\t* %s " + I18n.get(IExceptionMessage.BATCH_INVOICING_PROJECT_2) + "\n",
|
||||
batch.getDone());
|
||||
|
||||
comment +=
|
||||
String.format(
|
||||
"\t" + I18n.get(com.axelor.apps.base.exceptions.IExceptionMessage.ALARM_ENGINE_BATCH_4),
|
||||
batch.getAnomaly());
|
||||
|
||||
addComment(comment);
|
||||
super.stop();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.batch;
|
||||
|
||||
import com.axelor.apps.base.db.AppBusinessProject;
|
||||
import com.axelor.apps.base.service.administration.AbstractBatch;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.TeamTaskBusinessProjectService;
|
||||
import com.axelor.apps.businessproject.service.TimesheetLineBusinessService;
|
||||
import com.axelor.apps.businessproject.service.app.AppBusinessProjectService;
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.apps.hr.db.repo.TimesheetLineRepository;
|
||||
import com.axelor.db.JPA;
|
||||
import com.axelor.db.Query;
|
||||
import com.axelor.exception.db.repo.ExceptionOriginRepository;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BatchUpdateTaskService extends AbstractBatch {
|
||||
|
||||
protected AppBusinessProjectService appBusinessProjectService;
|
||||
protected TeamTaskBusinessProjectService teamTaskBusinessProjectService;
|
||||
protected TimesheetLineBusinessService timesheetLineBusinessService;
|
||||
protected TeamTaskRepository teamTaskRepo;
|
||||
protected TimesheetLineRepository timesheetLineRepo;
|
||||
|
||||
@Inject
|
||||
public BatchUpdateTaskService(
|
||||
TeamTaskBusinessProjectService teamTaskBusinessProjectService,
|
||||
AppBusinessProjectService appBusinessProjectService,
|
||||
TimesheetLineBusinessService timesheetLineBusinessService,
|
||||
TeamTaskRepository teamTaskRepo,
|
||||
TimesheetLineRepository timesheetLineRepo) {
|
||||
this.teamTaskBusinessProjectService = teamTaskBusinessProjectService;
|
||||
this.appBusinessProjectService = appBusinessProjectService;
|
||||
this.timesheetLineBusinessService = timesheetLineBusinessService;
|
||||
this.teamTaskRepo = teamTaskRepo;
|
||||
this.timesheetLineRepo = timesheetLineRepo;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process() {
|
||||
AppBusinessProject appBusinessProject = appBusinessProjectService.getAppBusinessProject();
|
||||
|
||||
Map<String, Object> contextValues = null;
|
||||
try {
|
||||
contextValues = ProjectInvoicingAssistantBatchService.createJsonContext(batch);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
|
||||
List<Object> updatedTaskList = new ArrayList<Object>();
|
||||
|
||||
String filter =
|
||||
!Strings.isNullOrEmpty(appBusinessProject.getExculdeTaskInvoicing())
|
||||
? "self.id NOT IN (SELECT id FROM TeamTask WHERE "
|
||||
+ appBusinessProject.getExculdeTaskInvoicing()
|
||||
+ ")"
|
||||
: "self.id NOT IN (0)";
|
||||
|
||||
Query<TeamTask> query =
|
||||
teamTaskRepo
|
||||
.all()
|
||||
.filter(
|
||||
filter
|
||||
+ " AND self.project.toInvoice = :invoiceable "
|
||||
+ "AND self.toInvoice = :toInvoice "
|
||||
+ "AND self.isTaskRefused = :refused")
|
||||
.bind("invoiceable", true)
|
||||
.bind("toInvoice", false)
|
||||
.bind("refused", false)
|
||||
.order("id");
|
||||
|
||||
int offset = 0;
|
||||
List<TeamTask> taskList;
|
||||
|
||||
while (!(taskList = query.fetch(FETCH_LIMIT, offset)).isEmpty()) {
|
||||
findBatch();
|
||||
offset += taskList.size();
|
||||
for (TeamTask teamTask : taskList) {
|
||||
try {
|
||||
teamTask = teamTaskBusinessProjectService.updateTask(teamTask, appBusinessProject);
|
||||
|
||||
if (teamTask.getToInvoice()) {
|
||||
offset--;
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("id", teamTask.getId());
|
||||
updatedTaskList.add(map);
|
||||
}
|
||||
|
||||
this.updateTimesheetLines(teamTask, contextValues);
|
||||
|
||||
} catch (Exception e) {
|
||||
incrementAnomaly();
|
||||
TraceBackService.trace(
|
||||
new Exception(
|
||||
String.format(
|
||||
I18n.get(IExceptionMessage.BATCH_TASK_UPDATION_1), teamTask.getId()),
|
||||
e),
|
||||
ExceptionOriginRepository.INVOICE_ORIGIN,
|
||||
batch.getId());
|
||||
}
|
||||
}
|
||||
JPA.clear();
|
||||
}
|
||||
findBatch();
|
||||
ProjectInvoicingAssistantBatchService.updateJsonObject(
|
||||
batch, updatedTaskList, "updatedTaskSet", contextValues);
|
||||
}
|
||||
|
||||
private void updateTimesheetLines(TeamTask teamTask, Map<String, Object> contextValues) {
|
||||
|
||||
if (!teamTask.getToInvoice()
|
||||
|| teamTask.getInvoicingType() != TeamTaskRepository.INVOICING_TYPE_TIME_SPENT) {
|
||||
return;
|
||||
}
|
||||
List<Object> updatedTimesheetLineList = new ArrayList<Object>();
|
||||
|
||||
List<TimesheetLine> timesheetLineList =
|
||||
timesheetLineRepo
|
||||
.all()
|
||||
.filter("self.teamTask.id = :taskId AND self.toInvoice = :toInvoice")
|
||||
.bind("taskId", teamTask.getId())
|
||||
.bind("toInvoice", false)
|
||||
.order("id")
|
||||
.fetch();
|
||||
|
||||
for (TimesheetLine timesheetLine : timesheetLineList) {
|
||||
try {
|
||||
timesheetLine = timesheetLineBusinessService.updateTimesheetLines(timesheetLine);
|
||||
|
||||
if (timesheetLine.getToInvoice()) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("id", timesheetLine.getId());
|
||||
updatedTimesheetLineList.add(map);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
incrementAnomaly();
|
||||
TraceBackService.trace(e, ExceptionOriginRepository.INVOICE_ORIGIN, batch.getId());
|
||||
}
|
||||
}
|
||||
ProjectInvoicingAssistantBatchService.updateJsonObject(
|
||||
batch, updatedTimesheetLineList, "updatedTimesheetLineSet", contextValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stop() {
|
||||
String comment = I18n.get(IExceptionMessage.BATCH_TASK_UPDATION_2);
|
||||
|
||||
comment +=
|
||||
String.format(
|
||||
"\t" + I18n.get(com.axelor.apps.base.exceptions.IExceptionMessage.ALARM_ENGINE_BATCH_4),
|
||||
batch.getAnomaly());
|
||||
|
||||
super.stop();
|
||||
addComment(comment);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.batch;
|
||||
|
||||
import com.axelor.apps.base.db.Batch;
|
||||
import com.axelor.apps.base.exceptions.IExceptionMessage;
|
||||
import com.axelor.apps.base.service.administration.AbstractBatchService;
|
||||
import com.axelor.apps.businessproject.db.ProjectInvoicingAssistantBatch;
|
||||
import com.axelor.apps.businessproject.db.repo.ProjectInvoicingAssistantBatchRepository;
|
||||
import com.axelor.db.EntityHelper;
|
||||
import com.axelor.db.Model;
|
||||
import com.axelor.db.mapper.Mapper;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.Context;
|
||||
import com.axelor.rpc.JsonContext;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
public class ProjectInvoicingAssistantBatchService extends AbstractBatchService {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Model> getModelClass() {
|
||||
return ProjectInvoicingAssistantBatch.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Batch run(Model model) throws AxelorException {
|
||||
|
||||
Batch batch;
|
||||
ProjectInvoicingAssistantBatch projectInvoicingAssistantBatch =
|
||||
(ProjectInvoicingAssistantBatch) model;
|
||||
|
||||
switch (projectInvoicingAssistantBatch.getActionSelect()) {
|
||||
case ProjectInvoicingAssistantBatchRepository.ACTION_UPDATE_TASKS:
|
||||
batch = updateTask(projectInvoicingAssistantBatch);
|
||||
break;
|
||||
|
||||
case ProjectInvoicingAssistantBatchRepository.ACTION_GENERATE_INVOICING_PROJECT:
|
||||
batch = generateInvoicingProject(projectInvoicingAssistantBatch);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new AxelorException(
|
||||
TraceBackRepository.CATEGORY_INCONSISTENCY,
|
||||
I18n.get(IExceptionMessage.BASE_BATCH_1),
|
||||
projectInvoicingAssistantBatch.getActionSelect(),
|
||||
projectInvoicingAssistantBatch.getCode());
|
||||
}
|
||||
return batch;
|
||||
}
|
||||
|
||||
public Batch updateTask(ProjectInvoicingAssistantBatch projectInvoicingAssistantBatch) {
|
||||
return Beans.get(BatchUpdateTaskService.class).run(projectInvoicingAssistantBatch);
|
||||
}
|
||||
|
||||
public Batch generateInvoicingProject(
|
||||
ProjectInvoicingAssistantBatch projectInvoicingAssistantBatch) {
|
||||
return Beans.get(BatchInvoicingProjectService.class).run(projectInvoicingAssistantBatch);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> createJsonContext(Batch batch) throws ClassNotFoundException {
|
||||
|
||||
Context context = new Context(batch.getClass());
|
||||
Class<? extends Model> klass =
|
||||
(Class<? extends Model>) Class.forName(batch.getClass().getName());
|
||||
|
||||
JsonContext jsonContext =
|
||||
new JsonContext(context, Mapper.of(klass).getProperty("attrs"), batch.getAttrs());
|
||||
|
||||
Map<String, Object> _map = new HashMap<String, Object>();
|
||||
_map.put("context", context);
|
||||
_map.put("jsonContext", jsonContext);
|
||||
return _map;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void updateJsonObject(
|
||||
Batch batch, List<Object> recordList, String field, Map<String, Object> contextValues) {
|
||||
|
||||
JsonContext jsonContext = (JsonContext) contextValues.get("jsonContext");
|
||||
List<Object> dataList = recordList;
|
||||
|
||||
if (jsonContext.containsKey(field)) {
|
||||
dataList =
|
||||
((List<Object>) jsonContext.get(field))
|
||||
.stream()
|
||||
.map(
|
||||
obj -> {
|
||||
if (Mapper.toMap(EntityHelper.getEntity(obj)).get("id") != null) {
|
||||
Map<String, Object> idMap = new HashMap<String, Object>();
|
||||
idMap.put("id", Mapper.toMap(EntityHelper.getEntity(obj)).get("id"));
|
||||
return idMap;
|
||||
}
|
||||
return obj;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
dataList.addAll(recordList);
|
||||
}
|
||||
|
||||
jsonContext.put(field, dataList);
|
||||
Context context = (Context) contextValues.get("context");
|
||||
batch.setAttrs(context.get("attrs").toString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public String getShowRecordIds(Batch batch, String field) throws ClassNotFoundException {
|
||||
|
||||
Context context = new Context(batch.getClass());
|
||||
Class<? extends Model> klass =
|
||||
(Class<? extends Model>) Class.forName(batch.getClass().getName());
|
||||
|
||||
JsonContext jsonContext =
|
||||
new JsonContext(context, Mapper.of(klass).getProperty("attrs"), batch.getAttrs());
|
||||
|
||||
List<Map<String, Object>> recordList = (List<Map<String, Object>>) jsonContext.get(field);
|
||||
|
||||
String ids =
|
||||
!CollectionUtils.isEmpty(recordList)
|
||||
? recordList
|
||||
.stream()
|
||||
.map(_map -> _map.get("id").toString())
|
||||
.collect(Collectors.joining(","))
|
||||
: null;
|
||||
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.projectgenerator;
|
||||
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.factory.ProjectGeneratorFactoryAlone;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.factory.ProjectGeneratorFactoryPhase;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.factory.ProjectGeneratorFactoryTask;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.factory.ProjectGeneratorFactoryTaskTemplate;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.ProjectGeneratorType;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public interface ProjectGeneratorFactory {
|
||||
|
||||
/**
|
||||
* Create and fill project from sale order.
|
||||
*
|
||||
* @param saleOrder Use for generate project.
|
||||
* @param localDateTime The date to use for create project's elements.
|
||||
* @return The project generate.
|
||||
* @throws AxelorException If a error occur on creating or filling.
|
||||
*/
|
||||
default Project generate(SaleOrder saleOrder, LocalDateTime localDateTime)
|
||||
throws AxelorException {
|
||||
Project project = create(saleOrder);
|
||||
fill(project, saleOrder, localDateTime);
|
||||
return project;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the factory associate to generator type.
|
||||
*
|
||||
* @param type The type of factory.
|
||||
* @return The factory associate to type.
|
||||
* @throws AxelorException If none factory is found for type.
|
||||
*/
|
||||
static ProjectGeneratorFactory getFactory(ProjectGeneratorType type) throws AxelorException {
|
||||
switch (type) {
|
||||
case PROJECT_ALONE:
|
||||
return Beans.get(ProjectGeneratorFactoryAlone.class);
|
||||
case TASK_BY_LINE:
|
||||
return Beans.get(ProjectGeneratorFactoryTask.class);
|
||||
case PHASE_BY_LINE:
|
||||
return Beans.get(ProjectGeneratorFactoryPhase.class);
|
||||
case TASK_TEMPLATE:
|
||||
return Beans.get(ProjectGeneratorFactoryTaskTemplate.class);
|
||||
default:
|
||||
throw new AxelorException(
|
||||
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
|
||||
I18n.get(IExceptionMessage.FACTORY_NO_FOUND));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the project from sale order.
|
||||
*
|
||||
* @param saleOrder Sale order to be use for create project.
|
||||
* @return The new project create.
|
||||
* @throws AxelorException If a error occur on creating.
|
||||
*/
|
||||
Project create(SaleOrder saleOrder) throws AxelorException;
|
||||
|
||||
/**
|
||||
* Fill the project with elements from sale order.
|
||||
*
|
||||
* @param project Project to be fill.
|
||||
* @param saleOrder Sale order to be use for fill project.
|
||||
* @param localDateTime The date to use for create project's elements.
|
||||
* @return The project fill with elements from sale order.
|
||||
* @throws AxelorException If a error occur on filling.
|
||||
*/
|
||||
ActionViewBuilder fill(Project project, SaleOrder saleOrder, LocalDateTime localDateTime)
|
||||
throws AxelorException;
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.projectgenerator.factory;
|
||||
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.ProjectBusinessService;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.ProjectGeneratorFactory;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class ProjectGeneratorFactoryAlone implements ProjectGeneratorFactory {
|
||||
|
||||
private ProjectBusinessService projectBusinessService;
|
||||
private ProjectRepository projectRepository;
|
||||
|
||||
@Inject
|
||||
public ProjectGeneratorFactoryAlone(
|
||||
ProjectBusinessService projectBusinessService, ProjectRepository projectRepository) {
|
||||
this.projectBusinessService = projectBusinessService;
|
||||
this.projectRepository = projectRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Project create(SaleOrder saleOrder) {
|
||||
Project project = projectBusinessService.generateProject(saleOrder);
|
||||
project.setIsProject(false);
|
||||
project.setIsBusinessProject(true);
|
||||
return projectRepository.save(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionViewBuilder fill(Project project, SaleOrder saleOrder, LocalDateTime localDateTime)
|
||||
throws AxelorException {
|
||||
throw new AxelorException(
|
||||
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
|
||||
I18n.get(IExceptionMessage.FACTORY_FILL_WITH_PROJECT_ALONE));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.projectgenerator.factory;
|
||||
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.base.db.repo.ProductRepository;
|
||||
import com.axelor.apps.businessproject.service.ProductTaskTemplateService;
|
||||
import com.axelor.apps.businessproject.service.ProjectBusinessService;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.ProjectGeneratorFactory;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderLineRepository;
|
||||
import com.axelor.apps.tool.StringTool;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
public class ProjectGeneratorFactoryPhase implements ProjectGeneratorFactory {
|
||||
|
||||
private ProjectBusinessService projectBusinessService;
|
||||
private ProjectRepository projectRepository;
|
||||
private SaleOrderLineRepository saleOrderLineRepository;
|
||||
private ProductTaskTemplateService productTaskTemplateService;
|
||||
|
||||
@Inject
|
||||
public ProjectGeneratorFactoryPhase(
|
||||
ProjectBusinessService projectBusinessService,
|
||||
ProjectRepository projectRepository,
|
||||
SaleOrderLineRepository saleOrderLineRepository,
|
||||
ProductTaskTemplateService productTaskTemplateService) {
|
||||
this.projectBusinessService = projectBusinessService;
|
||||
this.projectRepository = projectRepository;
|
||||
this.saleOrderLineRepository = saleOrderLineRepository;
|
||||
this.productTaskTemplateService = productTaskTemplateService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project create(SaleOrder saleOrder) {
|
||||
Project project = projectBusinessService.generateProject(saleOrder);
|
||||
project.setIsProject(true);
|
||||
project.setIsBusinessProject(true);
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ActionViewBuilder fill(Project project, SaleOrder saleOrder, LocalDateTime startDate) {
|
||||
List<Project> projects = new ArrayList<>();
|
||||
projectRepository.save(project);
|
||||
for (SaleOrderLine saleOrderLine : saleOrder.getSaleOrderLineList()) {
|
||||
Product product = saleOrderLine.getProduct();
|
||||
if (ProductRepository.PRODUCT_TYPE_SERVICE.equals(product.getProductTypeSelect())
|
||||
&& saleOrderLine.getSaleSupplySelect() == SaleOrderLineRepository.SALE_SUPPLY_PRODUCE) {
|
||||
Project phase = projectBusinessService.generatePhaseProject(saleOrderLine, project);
|
||||
phase.setFromDate(startDate);
|
||||
saleOrderLineRepository.save(saleOrderLine);
|
||||
projects.add(phase);
|
||||
|
||||
if (!CollectionUtils.isEmpty(product.getTaskTemplateSet())) {
|
||||
productTaskTemplateService.convert(
|
||||
product
|
||||
.getTaskTemplateSet()
|
||||
.stream()
|
||||
.filter(template -> Objects.isNull(template.getParentTaskTemplate()))
|
||||
.collect(Collectors.toList()),
|
||||
phase,
|
||||
null,
|
||||
startDate,
|
||||
saleOrderLine.getQty(),
|
||||
saleOrderLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ActionView.define(String.format("Project%s generated", (projects.size() > 1 ? "s" : "")))
|
||||
.model(Project.class.getName())
|
||||
.add("grid", "project-grid")
|
||||
.add("form", "project-form")
|
||||
.domain(String.format("self.id in (%s)", StringTool.getIdListString(projects)));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.projectgenerator.factory;
|
||||
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.base.db.repo.ProductRepository;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.ProjectBusinessService;
|
||||
import com.axelor.apps.businessproject.service.TeamTaskBusinessProjectService;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.ProjectGeneratorFactory;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderLineRepository;
|
||||
import com.axelor.apps.tool.StringTool;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ProjectGeneratorFactoryTask implements ProjectGeneratorFactory {
|
||||
|
||||
private ProjectBusinessService projectBusinessService;
|
||||
private ProjectRepository projectRepository;
|
||||
private TeamTaskBusinessProjectService teamTaskBusinessProjectService;
|
||||
private TeamTaskRepository teamTaskRepository;
|
||||
|
||||
@Inject
|
||||
public ProjectGeneratorFactoryTask(
|
||||
ProjectBusinessService projectBusinessService,
|
||||
ProjectRepository projectRepository,
|
||||
TeamTaskBusinessProjectService teamTaskBusinessProjectService,
|
||||
TeamTaskRepository teamTaskRepository) {
|
||||
this.projectBusinessService = projectBusinessService;
|
||||
this.projectRepository = projectRepository;
|
||||
this.teamTaskBusinessProjectService = teamTaskBusinessProjectService;
|
||||
this.teamTaskRepository = teamTaskRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project create(SaleOrder saleOrder) {
|
||||
Project project = projectBusinessService.generateProject(saleOrder);
|
||||
project.setIsProject(true);
|
||||
project.setIsBusinessProject(true);
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class, AxelorException.class})
|
||||
public ActionViewBuilder fill(Project project, SaleOrder saleOrder, LocalDateTime startDate)
|
||||
throws AxelorException {
|
||||
List<TeamTask> tasks = new ArrayList<>();
|
||||
projectRepository.save(project);
|
||||
for (SaleOrderLine saleOrderLine : saleOrder.getSaleOrderLineList()) {
|
||||
Product product = saleOrderLine.getProduct();
|
||||
boolean isTaskGenerated =
|
||||
teamTaskRepository
|
||||
.all()
|
||||
.filter("self.saleOrderLine = ? AND self.project = ?", saleOrderLine, project)
|
||||
.fetch()
|
||||
.size()
|
||||
> 0;
|
||||
if (ProductRepository.PRODUCT_TYPE_SERVICE.equals(product.getProductTypeSelect())
|
||||
&& saleOrderLine.getSaleSupplySelect() == SaleOrderLineRepository.SALE_SUPPLY_PRODUCE
|
||||
&& !(isTaskGenerated)) {
|
||||
|
||||
TeamTask task =
|
||||
teamTaskBusinessProjectService.create(saleOrderLine, project, project.getAssignedTo());
|
||||
|
||||
if (saleOrder.getToInvoiceViaTask()) {
|
||||
task.setInvoicingType(TeamTaskRepository.INVOICING_TYPE_PACKAGE);
|
||||
}
|
||||
|
||||
task.setTaskDate(startDate.toLocalDate());
|
||||
task.setUnitPrice(product.getSalePrice());
|
||||
task.setExTaxTotal(saleOrderLine.getExTaxTotal());
|
||||
if (project.getIsInvoicingTimesheet()) {
|
||||
task.setToInvoice(true);
|
||||
} else {
|
||||
task.setToInvoice(false);
|
||||
}
|
||||
teamTaskRepository.save(task);
|
||||
tasks.add(task);
|
||||
}
|
||||
}
|
||||
if (tasks == null || tasks.isEmpty()) {
|
||||
throw new AxelorException(
|
||||
TraceBackRepository.CATEGORY_NO_VALUE,
|
||||
I18n.get(IExceptionMessage.SALE_ORDER_GENERATE_FILL_PROJECT_ERROR_1));
|
||||
}
|
||||
|
||||
return ActionView.define(String.format("Task%s generated", (tasks.size() > 1 ? "s" : "")))
|
||||
.model(TeamTask.class.getName())
|
||||
.add("grid", "team-task-grid")
|
||||
.add("form", "team-task-form")
|
||||
.domain(String.format("self.id in (%s)", StringTool.getIdListString(tasks)));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.service.projectgenerator.factory;
|
||||
|
||||
import com.axelor.apps.base.db.Product;
|
||||
import com.axelor.apps.base.db.repo.ProductRepository;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.ProductTaskTemplateService;
|
||||
import com.axelor.apps.businessproject.service.ProjectBusinessService;
|
||||
import com.axelor.apps.businessproject.service.TeamTaskBusinessProjectService;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.ProjectGeneratorFactory;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderLineRepository;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
public class ProjectGeneratorFactoryTaskTemplate implements ProjectGeneratorFactory {
|
||||
|
||||
private ProjectBusinessService projectBusinessService;
|
||||
private ProjectRepository projectRepository;
|
||||
private TeamTaskBusinessProjectService teamTaskService;
|
||||
private TeamTaskRepository teamTaskRepository;
|
||||
private ProductTaskTemplateService productTaskTemplateService;
|
||||
|
||||
@Inject
|
||||
public ProjectGeneratorFactoryTaskTemplate(
|
||||
ProjectBusinessService projectBusinessService,
|
||||
ProjectRepository projectRepository,
|
||||
TeamTaskBusinessProjectService teamTaskService,
|
||||
TeamTaskRepository teamTaskRepository,
|
||||
ProductTaskTemplateService productTaskTemplateService) {
|
||||
this.projectBusinessService = projectBusinessService;
|
||||
this.projectRepository = projectRepository;
|
||||
this.teamTaskService = teamTaskService;
|
||||
this.teamTaskRepository = teamTaskRepository;
|
||||
this.productTaskTemplateService = productTaskTemplateService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project create(SaleOrder saleOrder) {
|
||||
Project project = projectBusinessService.generateProject(saleOrder);
|
||||
project.setIsProject(true);
|
||||
project.setIsBusinessProject(true);
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class, AxelorException.class})
|
||||
public ActionViewBuilder fill(Project project, SaleOrder saleOrder, LocalDateTime startDate)
|
||||
throws AxelorException {
|
||||
List<TeamTask> tasks = new ArrayList<>();
|
||||
TeamTask root;
|
||||
|
||||
root =
|
||||
teamTaskRepository
|
||||
.all()
|
||||
.filter(
|
||||
"self.project = ? AND self.assignedTo = ? AND self.name = ?",
|
||||
project,
|
||||
project.getAssignedTo(),
|
||||
saleOrder.getFullName())
|
||||
.fetchOne();
|
||||
|
||||
projectRepository.save(project);
|
||||
|
||||
for (SaleOrderLine orderLine : saleOrder.getSaleOrderLineList()) {
|
||||
Product product = orderLine.getProduct();
|
||||
if (product != null
|
||||
&& !((ProductRepository.PROCUREMENT_METHOD_PRODUCE.equals(
|
||||
product.getProcurementMethodSelect())
|
||||
|| orderLine.getSaleSupplySelect() == SaleOrderLineRepository.SALE_SUPPLY_PRODUCE)
|
||||
&& ProductRepository.PRODUCT_TYPE_SERVICE.equals(product.getProductTypeSelect()))) {
|
||||
continue;
|
||||
}
|
||||
boolean isTaskGenerated =
|
||||
teamTaskRepository
|
||||
.all()
|
||||
.filter("self.saleOrderLine = ? AND self.project = ?", orderLine, project)
|
||||
.fetch()
|
||||
.size()
|
||||
> 0;
|
||||
if (root == null) {
|
||||
root = teamTaskService.create(saleOrder.getFullName(), project, project.getAssignedTo());
|
||||
root.setTaskDate(startDate.toLocalDate());
|
||||
tasks.add(teamTaskRepository.save(root));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(product.getTaskTemplateSet()) && !(isTaskGenerated)) {
|
||||
List<TeamTask> convertedTasks =
|
||||
productTaskTemplateService.convert(
|
||||
product
|
||||
.getTaskTemplateSet()
|
||||
.stream()
|
||||
.filter(template -> Objects.isNull(template.getParentTaskTemplate()))
|
||||
.collect(Collectors.toList()),
|
||||
project,
|
||||
root,
|
||||
startDate,
|
||||
orderLine.getQty(),
|
||||
orderLine);
|
||||
convertedTasks.stream().forEach(task -> task.setSaleOrderLine(orderLine));
|
||||
tasks.addAll(convertedTasks);
|
||||
} else if (CollectionUtils.isEmpty(product.getTaskTemplateSet()) && !(isTaskGenerated)) {
|
||||
TeamTask childTask =
|
||||
teamTaskService.create(orderLine.getFullName(), project, project.getAssignedTo());
|
||||
this.updateTask(root, childTask, orderLine);
|
||||
|
||||
tasks.add(teamTaskRepository.save(childTask));
|
||||
}
|
||||
}
|
||||
if (root == null) {
|
||||
throw new AxelorException(
|
||||
TraceBackRepository.CATEGORY_NO_VALUE,
|
||||
I18n.get(IExceptionMessage.SALE_ORDER_GENERATE_FILL_PROJECT_ERROR_2));
|
||||
}
|
||||
return ActionView.define("Tasks")
|
||||
.model(TeamTask.class.getName())
|
||||
.add("grid", "team-task-grid")
|
||||
.add("form", "team-task-form")
|
||||
.domain("self.parentTask = " + root.getId());
|
||||
}
|
||||
|
||||
private void updateTask(TeamTask root, TeamTask childTask, SaleOrderLine orderLine) {
|
||||
childTask.setParentTask(root);
|
||||
childTask.setQuantity(orderLine.getQty());
|
||||
Product product = orderLine.getProduct();
|
||||
childTask.setProduct(product);
|
||||
childTask.setExTaxTotal(orderLine.getExTaxTotal());
|
||||
childTask.setUnitPrice(product != null ? product.getSalePrice() : null);
|
||||
childTask.setUnit(product != null ? product.getUnit() : null);
|
||||
childTask.setSaleOrderLine(orderLine);
|
||||
if (orderLine.getSaleOrder().getToInvoiceViaTask()) {
|
||||
childTask.setToInvoice(true);
|
||||
childTask.setInvoicingType(TeamTaskRepository.INVOICING_TYPE_PACKAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.translation;
|
||||
|
||||
public interface ITranslation {
|
||||
|
||||
public static final String JOB_COSTING_APP_NAME = /*$$(*/ "value:Job costing"; /*)*/
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.ExpenseLineProjectService;
|
||||
import com.axelor.apps.hr.db.ExpenseLine;
|
||||
import com.axelor.apps.hr.db.repo.ExpenseLineRepository;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ExpenseLineProjectController {
|
||||
|
||||
/**
|
||||
* Set project from context selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void setProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
project = Beans.get(ProjectRepository.class).find(project.getId());
|
||||
|
||||
setProject(request, response, project);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setProject(ActionRequest request, ActionResponse response, Project project) {
|
||||
|
||||
List<Map<String, Object>> expenseLineSet =
|
||||
(List<Map<String, Object>>) request.getContext().get("expenseLineSet");
|
||||
|
||||
if (expenseLineSet == null || expenseLineSet.isEmpty()) {
|
||||
response.setFlash(IExceptionMessage.LINES_NOT_SELECTED);
|
||||
} else {
|
||||
List<Long> lineIds =
|
||||
expenseLineSet
|
||||
.stream()
|
||||
.map(it -> Long.parseLong(it.get("id").toString()))
|
||||
.collect(Collectors.toList());
|
||||
Beans.get(ExpenseLineProjectService.class).setProject(lineIds, project);
|
||||
response.setAttr("$expenseLineSet", "hidden", true);
|
||||
response.setAttr("addSelectedExpenseLinesBtn", "hidden", true);
|
||||
response.setAttr("unlinkSelectedExpenseLinesBtn", "hidden", true);
|
||||
response.setAttr("cancelManageExpenseLinesBtn", "hidden", true);
|
||||
response.setAttr("expenseLinePanel", "refresh", true);
|
||||
response.setAttr("expensePanel", "refresh", true);
|
||||
response.setAttr("selectNewExpenseLinesBtn", "readonly", false);
|
||||
response.setAttr("manageExpenseLinesBtn", "readonly", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove project from selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void unsetProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
setProject(request, response, null);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invert value of 'toInvoice' field and save the record
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
@Transactional
|
||||
public void updateToInvoice(ActionRequest request, ActionResponse response) {
|
||||
ExpenseLineRepository expenseLineRepository = Beans.get(ExpenseLineRepository.class);
|
||||
try {
|
||||
ExpenseLine expenseLine = request.getContext().asType(ExpenseLine.class);
|
||||
expenseLine = expenseLineRepository.find(expenseLine.getId());
|
||||
expenseLine.setToInvoice(!expenseLine.getToInvoice());
|
||||
expenseLineRepository.save(expenseLine);
|
||||
response.setValue("toInvoice", expenseLine.getToInvoice());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.account.db.InvoiceLine;
|
||||
import com.axelor.apps.account.db.PaymentCondition;
|
||||
import com.axelor.apps.account.db.PaymentMode;
|
||||
import com.axelor.apps.account.db.repo.InvoiceRepository;
|
||||
import com.axelor.apps.account.exception.IExceptionMessage;
|
||||
import com.axelor.apps.base.db.Company;
|
||||
import com.axelor.apps.base.db.Currency;
|
||||
import com.axelor.apps.base.db.Partner;
|
||||
import com.axelor.apps.base.db.PriceList;
|
||||
import com.axelor.apps.base.db.Wizard;
|
||||
import com.axelor.apps.businessproject.service.InvoiceServiceProjectImpl;
|
||||
import com.axelor.apps.businessproject.service.SaleOrderInvoiceProjectServiceImpl;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.db.JPA;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Singleton
|
||||
public class InvoiceController {
|
||||
|
||||
// Generate single invoice from several
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public void mergeInvoice(ActionRequest request, ActionResponse response) {
|
||||
List<Invoice> invoiceList = new ArrayList<Invoice>();
|
||||
List<Long> invoiceIdList = new ArrayList<Long>();
|
||||
boolean fromPopup = false;
|
||||
|
||||
if (request.getContext().get("invoiceToMerge") != null) {
|
||||
|
||||
if (request.getContext().get("invoiceToMerge") instanceof List) {
|
||||
// No confirmation popup, invoices are content in a parameter list
|
||||
List<Map> invoiceMap = (List<Map>) request.getContext().get("invoiceToMerge");
|
||||
for (Map map : invoiceMap) {
|
||||
invoiceIdList.add(new Long((Integer) map.get("id")));
|
||||
}
|
||||
} else {
|
||||
// After confirmation popup, invoice's id are in a string separated by ","
|
||||
String invoiceIdListStr = (String) request.getContext().get("invoiceToMerge");
|
||||
for (String invoiceId : invoiceIdListStr.split(",")) {
|
||||
invoiceIdList.add(new Long(invoiceId));
|
||||
}
|
||||
fromPopup = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if company, currency and partner are the same for all selected invoices
|
||||
Company commonCompany = null;
|
||||
Currency commonCurrency = null;
|
||||
Partner commonPartner = null;
|
||||
PaymentCondition commonPaymentCondition = null;
|
||||
// Useful to determine if a difference exists between payment conditions of all invoices
|
||||
boolean existPaymentConditionDiff = false;
|
||||
Partner commonContactPartner = null;
|
||||
// Useful to determine if a difference exists between contact partners of all purchase orders
|
||||
boolean existContactPartnerDiff = false;
|
||||
PriceList commonPriceList = null;
|
||||
// Useful to determine if a difference exists between price lists of all purchase orders
|
||||
boolean existPriceListDiff = false;
|
||||
PaymentMode commonPaymentMode = null;
|
||||
// Useful to determine if a difference exists between locations of all purchase orders
|
||||
boolean existPaymentModeDiff = false;
|
||||
SaleOrder commonSaleOrder = null;
|
||||
// Useful to check if all sale orders are null (since this field is not required)
|
||||
boolean saleOrderIsNull = false;
|
||||
Project commonProject = null;
|
||||
// Useful to check if all projects are null (since this field is not required)
|
||||
boolean projectIsNull = false;
|
||||
|
||||
Invoice invoiceTemp;
|
||||
int count = 1;
|
||||
for (Long invoiceId : invoiceIdList) {
|
||||
invoiceTemp = JPA.em().find(Invoice.class, invoiceId);
|
||||
invoiceList.add(invoiceTemp);
|
||||
if (count == 1) {
|
||||
commonCompany = invoiceTemp.getCompany();
|
||||
commonCurrency = invoiceTemp.getCurrency();
|
||||
commonPartner = invoiceTemp.getPartner();
|
||||
commonPaymentCondition = invoiceTemp.getPaymentCondition();
|
||||
commonContactPartner = invoiceTemp.getContactPartner();
|
||||
commonPriceList = invoiceTemp.getPriceList();
|
||||
commonPaymentMode = invoiceTemp.getPaymentMode();
|
||||
commonSaleOrder = invoiceTemp.getSaleOrder();
|
||||
commonProject = invoiceTemp.getProject();
|
||||
if (commonSaleOrder == null) {
|
||||
saleOrderIsNull = true;
|
||||
}
|
||||
if (commonProject == null) {
|
||||
projectIsNull = true;
|
||||
}
|
||||
} else {
|
||||
if (commonCompany != null && !commonCompany.equals(invoiceTemp.getCompany())) {
|
||||
commonCompany = null;
|
||||
}
|
||||
if (commonCurrency != null && !commonCurrency.equals(invoiceTemp.getCurrency())) {
|
||||
commonCurrency = null;
|
||||
}
|
||||
if (commonPartner != null && !commonPartner.equals(invoiceTemp.getPartner())) {
|
||||
commonPartner = null;
|
||||
}
|
||||
if (commonPaymentCondition != null
|
||||
&& !commonPaymentCondition.equals(invoiceTemp.getPaymentCondition())) {
|
||||
commonPaymentCondition = null;
|
||||
existPaymentConditionDiff = true;
|
||||
}
|
||||
if (commonContactPartner != null
|
||||
&& !commonContactPartner.equals(invoiceTemp.getContactPartner())) {
|
||||
commonContactPartner = null;
|
||||
existContactPartnerDiff = true;
|
||||
}
|
||||
if (commonPriceList != null && !commonPriceList.equals(invoiceTemp.getPriceList())) {
|
||||
commonPriceList = null;
|
||||
existPriceListDiff = true;
|
||||
}
|
||||
if (commonPaymentMode != null && !commonPaymentMode.equals(invoiceTemp.getPaymentMode())) {
|
||||
commonPaymentMode = null;
|
||||
existPaymentModeDiff = true;
|
||||
}
|
||||
if (commonSaleOrder != null && !commonSaleOrder.equals(invoiceTemp.getSaleOrder())) {
|
||||
commonSaleOrder = null;
|
||||
}
|
||||
if (commonProject != null && !commonProject.equals(invoiceTemp.getProject())) {
|
||||
commonProject = null;
|
||||
}
|
||||
if (invoiceTemp.getSaleOrder() != null) {
|
||||
saleOrderIsNull = false;
|
||||
}
|
||||
if (invoiceTemp.getProject() != null) {
|
||||
projectIsNull = false;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
StringBuilder fieldErrors = new StringBuilder();
|
||||
if (commonCurrency == null) {
|
||||
fieldErrors.append(I18n.get(IExceptionMessage.INVOICE_MERGE_ERROR_CURRENCY));
|
||||
}
|
||||
if (commonCompany == null) {
|
||||
if (fieldErrors.length() > 0) {
|
||||
fieldErrors.append("<br/>");
|
||||
}
|
||||
fieldErrors.append(I18n.get(IExceptionMessage.INVOICE_MERGE_ERROR_COMPANY));
|
||||
}
|
||||
if (commonPartner == null) {
|
||||
if (fieldErrors.length() > 0) {
|
||||
fieldErrors.append("<br/>");
|
||||
}
|
||||
fieldErrors.append(I18n.get(IExceptionMessage.INVOICE_MERGE_ERROR_PARTNER));
|
||||
}
|
||||
|
||||
if (commonSaleOrder == null && saleOrderIsNull == false) {
|
||||
if (fieldErrors.length() > 0) {
|
||||
fieldErrors.append("<br/>");
|
||||
}
|
||||
fieldErrors.append(I18n.get(IExceptionMessage.INVOICE_MERGE_ERROR_SALEORDER));
|
||||
}
|
||||
|
||||
if (commonProject == null && projectIsNull == false) {
|
||||
if (fieldErrors.length() > 0) {
|
||||
fieldErrors.append("<br/>");
|
||||
}
|
||||
fieldErrors.append(I18n.get(IExceptionMessage.INVOICE_MERGE_ERROR_PROJECT));
|
||||
}
|
||||
|
||||
if (fieldErrors.length() > 0) {
|
||||
response.setFlash(fieldErrors.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if contactPartner or priceList or paymentMode or paymentCondition or saleOrder are
|
||||
// content in parameters
|
||||
if (request.getContext().get("contactPartner") != null) {
|
||||
commonContactPartner =
|
||||
JPA.em()
|
||||
.find(
|
||||
Partner.class,
|
||||
new Long((Integer) ((Map) request.getContext().get("contactPartner")).get("id")));
|
||||
}
|
||||
if (request.getContext().get("priceList") != null) {
|
||||
commonPriceList =
|
||||
JPA.em()
|
||||
.find(
|
||||
PriceList.class,
|
||||
new Long((Integer) ((Map) request.getContext().get("priceList")).get("id")));
|
||||
}
|
||||
if (request.getContext().get("paymentMode") != null) {
|
||||
commonPaymentMode =
|
||||
JPA.em()
|
||||
.find(
|
||||
PaymentMode.class,
|
||||
new Long((Integer) ((Map) request.getContext().get("paymentMode")).get("id")));
|
||||
}
|
||||
if (request.getContext().get("paymentCondition") != null) {
|
||||
commonPaymentCondition =
|
||||
JPA.em()
|
||||
.find(
|
||||
PaymentCondition.class,
|
||||
new Long(
|
||||
(Integer) ((Map) request.getContext().get("paymentCondition")).get("id")));
|
||||
}
|
||||
|
||||
if (!fromPopup
|
||||
&& (existPaymentConditionDiff
|
||||
|| existContactPartnerDiff
|
||||
|| existPriceListDiff
|
||||
|| existPaymentModeDiff)) {
|
||||
// Need to display intermediate screen to select some values
|
||||
ActionViewBuilder confirmView =
|
||||
ActionView.define("Confirm merge invoice")
|
||||
.model(Wizard.class.getName())
|
||||
.add("form", "customer-invoices-merge-confirm-form")
|
||||
.param("popup", "true")
|
||||
.param("show-toolbar", "false")
|
||||
.param("show-confirm", "false")
|
||||
.param("popup-save", "false")
|
||||
.param("forceEdit", "true");
|
||||
|
||||
if (existContactPartnerDiff) {
|
||||
confirmView.context("contextContactPartnerToCheck", "true");
|
||||
confirmView.context("contextPartnerId", commonPartner.getId().toString());
|
||||
}
|
||||
if (existPriceListDiff) {
|
||||
confirmView.context("contextPriceListToCheck", "true");
|
||||
}
|
||||
if (existPaymentModeDiff) {
|
||||
confirmView.context("contextPaymentModeToCheck", "true");
|
||||
}
|
||||
if (existPaymentConditionDiff) {
|
||||
confirmView.context("contextPaymentConditionToCheck", "true");
|
||||
}
|
||||
confirmView.context("invoiceToMerge", Joiner.on(",").join(invoiceIdList));
|
||||
|
||||
response.setView(confirmView.map());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Invoice invoice =
|
||||
Beans.get(SaleOrderInvoiceProjectServiceImpl.class)
|
||||
.mergeInvoice(
|
||||
invoiceList,
|
||||
commonCompany,
|
||||
commonCurrency,
|
||||
commonPartner,
|
||||
commonContactPartner,
|
||||
commonPriceList,
|
||||
commonPaymentMode,
|
||||
commonPaymentCondition,
|
||||
commonSaleOrder,
|
||||
commonProject);
|
||||
if (invoice != null) {
|
||||
// Open the generated invoice in a new tab
|
||||
response.setView(
|
||||
ActionView.define("Invoice")
|
||||
.model(Invoice.class.getName())
|
||||
.add("grid", "invoice-grid")
|
||||
.add("form", "invoice-form")
|
||||
.param("forceEdit", "true")
|
||||
.context("_showRecord", String.valueOf(invoice.getId()))
|
||||
.map());
|
||||
response.setCanClose(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
response.setFlash(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void exportAnnex(ActionRequest request, ActionResponse response) throws AxelorException {
|
||||
|
||||
Invoice invoice =
|
||||
Beans.get(InvoiceRepository.class).find(request.getContext().asType(Invoice.class).getId());
|
||||
|
||||
try {
|
||||
List<String> reportInfo =
|
||||
Beans.get(InvoiceServiceProjectImpl.class)
|
||||
.editInvoiceAnnex(invoice, invoice.getId().toString(), false);
|
||||
|
||||
if (reportInfo == null || reportInfo.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
response.setView(ActionView.define(reportInfo.get(0)).add("html", reportInfo.get(1)).map());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateLines(ActionRequest request, ActionResponse response) throws AxelorException {
|
||||
Invoice invoice = request.getContext().asType(Invoice.class);
|
||||
invoice = Beans.get(InvoiceRepository.class).find(invoice.getId());
|
||||
|
||||
for (InvoiceLine invoiceLine : invoice.getInvoiceLineList()) {
|
||||
invoiceLine.setProject(invoice.getProject());
|
||||
}
|
||||
response.setValue("invoiceLineList", invoice.getInvoiceLineList());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.InvoiceLineProjectService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class InvoiceLineProjectController {
|
||||
|
||||
/**
|
||||
* Set project from context selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void setCustomerInvoiceLineProject(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
project = Beans.get(ProjectRepository.class).find(project.getId());
|
||||
|
||||
setCustomerInvoiceLineProject(request, response, project);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCustomerInvoiceLineProject(
|
||||
ActionRequest request, ActionResponse response, Project project) {
|
||||
|
||||
List<Map<String, Object>> customerInvoiceLineSet =
|
||||
(List<Map<String, Object>>) request.getContext().get("customerInvoiceLineSet");
|
||||
|
||||
if (customerInvoiceLineSet == null || customerInvoiceLineSet.isEmpty()) {
|
||||
response.setFlash(IExceptionMessage.LINES_NOT_SELECTED);
|
||||
} else {
|
||||
List<Long> lineIds =
|
||||
customerInvoiceLineSet
|
||||
.stream()
|
||||
.map(it -> Long.parseLong(it.get("id").toString()))
|
||||
.collect(Collectors.toList());
|
||||
Beans.get(InvoiceLineProjectService.class).setProject(lineIds, project);
|
||||
response.setAttr("$customerInvoiceLineSet", "hidden", true);
|
||||
response.setAttr("addSelectedCustomerInvoiceLinesBtn", "hidden", true);
|
||||
response.setAttr("unlinkSelectedCustomerInvoiceLinesBtn", "hidden", true);
|
||||
response.setAttr("cancelManageCustomerInvoiceLinesBtn", "hidden", true);
|
||||
response.setAttr("customerInvoiceLinePanel", "refresh", true);
|
||||
response.setAttr("customerInvoicePanel", "refresh", true);
|
||||
response.setAttr("selectNewCustomerInvoiceLinesBtn", "readonly", false);
|
||||
response.setAttr("manageCustomerInvoiceLinesBtn", "readonly", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove project from selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void unsetCustomerInvoiceLineProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
setCustomerInvoiceLineProject(request, response, null);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set project from context selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void setSupplierInvoiceLineProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
project = Beans.get(ProjectRepository.class).find(project.getId());
|
||||
|
||||
setSupplierInvoiceLineProject(request, response, project);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSupplierInvoiceLineProject(
|
||||
ActionRequest request, ActionResponse response, Project project) {
|
||||
|
||||
List<Map<String, Object>> supplierInvoiceLineSet =
|
||||
(List<Map<String, Object>>) request.getContext().get("supplierInvoiceLineSet");
|
||||
|
||||
if (supplierInvoiceLineSet == null || supplierInvoiceLineSet.isEmpty()) {
|
||||
response.setFlash(IExceptionMessage.LINES_NOT_SELECTED);
|
||||
} else {
|
||||
List<Long> lineIds =
|
||||
supplierInvoiceLineSet
|
||||
.stream()
|
||||
.map(it -> Long.parseLong(it.get("id").toString()))
|
||||
.collect(Collectors.toList());
|
||||
Beans.get(InvoiceLineProjectService.class).setProject(lineIds, project);
|
||||
response.setAttr("$supplierInvoiceLineSet", "hidden", true);
|
||||
response.setAttr("addSelectedSupplierInvoiceLinesBtn", "hidden", true);
|
||||
response.setAttr("unlinkSelectedSupplierInvoiceLinesBtn", "hidden", true);
|
||||
response.setAttr("cancelManageSupplierInvoiceLinesBtn", "hidden", true);
|
||||
response.setAttr("supplierInvoiceLinePanel", "refresh", true);
|
||||
response.setAttr("supplierInvoicePanel", "refresh", true);
|
||||
response.setAttr("selectNewSupplierInvoiceLinesBtn", "readonly", false);
|
||||
response.setAttr("manageSupplierInvoiceLinesBtn", "readonly", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove project from selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void unsetSupplierInvoiceLineProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
setSupplierInvoiceLineProject(request, response, null);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.account.db.Invoice;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.db.repo.InvoicingProjectRepository;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.InvoicingProjectService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.db.repo.TraceBackRepository;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
|
||||
@Singleton
|
||||
public class InvoicingProjectController {
|
||||
|
||||
public void generateInvoice(ActionRequest request, ActionResponse response)
|
||||
throws AxelorException {
|
||||
InvoicingProject invoicingProject = request.getContext().asType(InvoicingProject.class);
|
||||
invoicingProject = Beans.get(InvoicingProjectRepository.class).find(invoicingProject.getId());
|
||||
|
||||
if (invoicingProject.getSaleOrderLineSet().isEmpty()
|
||||
&& invoicingProject.getPurchaseOrderLineSet().isEmpty()
|
||||
&& invoicingProject.getLogTimesSet().isEmpty()
|
||||
&& invoicingProject.getExpenseLineSet().isEmpty()
|
||||
&& invoicingProject.getProjectSet().isEmpty()
|
||||
&& invoicingProject.getTeamTaskSet().isEmpty()) {
|
||||
throw new AxelorException(
|
||||
invoicingProject,
|
||||
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
|
||||
I18n.get(IExceptionMessage.INVOICING_PROJECT_EMPTY));
|
||||
}
|
||||
if (invoicingProject.getProject() == null) {
|
||||
throw new AxelorException(
|
||||
invoicingProject,
|
||||
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
|
||||
I18n.get(IExceptionMessage.INVOICING_PROJECT_PROJECT));
|
||||
}
|
||||
if (invoicingProject.getProject().getClientPartner() == null) {
|
||||
throw new AxelorException(
|
||||
invoicingProject,
|
||||
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
|
||||
I18n.get(IExceptionMessage.INVOICING_PROJECT_PROJECT_PARTNER));
|
||||
}
|
||||
|
||||
Invoice invoice = Beans.get(InvoicingProjectService.class).generateInvoice(invoicingProject);
|
||||
try {
|
||||
if (invoice != null) {
|
||||
Beans.get(InvoicingProjectService.class).generateAnnex(invoicingProject);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
response.setReload(true);
|
||||
response.setView(
|
||||
ActionView.define("Invoice")
|
||||
.model(Invoice.class.getName())
|
||||
.add("form", "invoice-form")
|
||||
.param("forceEdit", "true")
|
||||
.context("_showRecord", String.valueOf(invoice.getId()))
|
||||
.map());
|
||||
}
|
||||
|
||||
public void fillIn(ActionRequest request, ActionResponse response) throws AxelorException {
|
||||
InvoicingProject invoicingProject = request.getContext().asType(InvoicingProject.class);
|
||||
InvoicingProjectService invoicingProjectService = Beans.get(InvoicingProjectService.class);
|
||||
Project project = invoicingProject.getProject();
|
||||
if (project == null) {
|
||||
throw new AxelorException(
|
||||
TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
|
||||
I18n.get(IExceptionMessage.INVOICING_PROJECT_PROJECT));
|
||||
}
|
||||
invoicingProjectService.clearLines(invoicingProject);
|
||||
invoicingProjectService.setLines(invoicingProject, project, 0);
|
||||
response.setValues(invoicingProject);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.ReportFactory;
|
||||
import com.axelor.apps.base.db.Partner;
|
||||
import com.axelor.apps.base.db.repo.PriceListRepository;
|
||||
import com.axelor.apps.base.service.PartnerPriceListService;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.report.IReport;
|
||||
import com.axelor.apps.businessproject.service.InvoicingProjectService;
|
||||
import com.axelor.apps.businessproject.service.ProjectBusinessService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrder;
|
||||
import com.axelor.apps.report.engine.ReportSettings;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.Singleton;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.math.BigDecimal;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Singleton
|
||||
public class ProjectController {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
public void generateQuotation(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
SaleOrder order = Beans.get(ProjectBusinessService.class).generateQuotation(project);
|
||||
response.setView(
|
||||
ActionView.define("Sale Order")
|
||||
.model(SaleOrder.class.getName())
|
||||
.add("form", "sale-order-form")
|
||||
.context("_showRecord", String.valueOf(order.getId()))
|
||||
.map());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void generatePurchaseQuotation(ActionRequest request, ActionResponse response) {
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
if (project.getId() != null) {
|
||||
response.setView(
|
||||
ActionView.define("Purchase Order")
|
||||
.model(PurchaseOrder.class.getName())
|
||||
.add("form", "purchase-order-form")
|
||||
.add("grid", "purchase-order-quotation-grid")
|
||||
.context("_project", Beans.get(ProjectRepository.class).find(project.getId()))
|
||||
.map());
|
||||
}
|
||||
}
|
||||
|
||||
public void printProject(ActionRequest request, ActionResponse response) throws AxelorException {
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
|
||||
String name = I18n.get("Project") + " " + (project.getCode() != null ? project.getCode() : "");
|
||||
|
||||
String fileLink =
|
||||
ReportFactory.createReport(IReport.PROJECT, name + "-${date}")
|
||||
.addParam("ProjectId", project.getId())
|
||||
.addParam("Locale", ReportSettings.getPrintingLocale(null))
|
||||
.toAttach(project)
|
||||
.generate()
|
||||
.getFileLink();
|
||||
|
||||
logger.debug("Printing " + name);
|
||||
|
||||
response.setView(ActionView.define(name).add("html", fileLink).map());
|
||||
}
|
||||
|
||||
// TODO: Duration is removed. Have to change calcuation
|
||||
public void computeProgress(ActionRequest request, ActionResponse response) {
|
||||
|
||||
// Project project = request.getContext().asType(Project.class);
|
||||
|
||||
BigDecimal duration = BigDecimal.ZERO;
|
||||
// if (BigDecimal.ZERO.compareTo(project.getDuration()) != 0) {
|
||||
// duration =
|
||||
// project
|
||||
// .getTimeSpent()
|
||||
// .add(project.getLeadDelay())
|
||||
// .divide(project.getDuration(), 2, java.math.RoundingMode.HALF_UP)
|
||||
// .multiply(new BigDecimal(100));
|
||||
// }
|
||||
|
||||
if (duration.compareTo(BigDecimal.ZERO) == -1 || duration.compareTo(new BigDecimal(100)) == 1) {
|
||||
duration = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
response.setValue("progress", duration);
|
||||
}
|
||||
|
||||
public void countToInvoice(ActionRequest request, ActionResponse response) {
|
||||
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
|
||||
int toInvoiceCount = 0;
|
||||
if (project.getId() != null) {
|
||||
toInvoiceCount = Beans.get(InvoicingProjectService.class).countToInvoice(project);
|
||||
}
|
||||
|
||||
response.setValue("$toInvoiceCounter", toInvoiceCount);
|
||||
}
|
||||
|
||||
public void showInvoicingProjects(ActionRequest request, ActionResponse response) {
|
||||
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
project = Beans.get(ProjectRepository.class).find(project.getId());
|
||||
|
||||
response.setView(
|
||||
ActionView.define("Invoice Buisness Project")
|
||||
.model(InvoicingProject.class.getName())
|
||||
.add("form", "invoicing-project-form")
|
||||
.param("forceEdit", "true")
|
||||
.param("show-toolbar", "false")
|
||||
.context("_project", project)
|
||||
.map());
|
||||
}
|
||||
|
||||
public void printPlannifAndCost(ActionRequest request, ActionResponse response)
|
||||
throws AxelorException {
|
||||
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
|
||||
String name = I18n.get("Planification and costs");
|
||||
|
||||
if (project.getCode() != null) {
|
||||
name += " (" + project.getCode() + ")";
|
||||
}
|
||||
|
||||
String fileLink =
|
||||
ReportFactory.createReport(IReport.PLANNIF_AND_COST, name)
|
||||
.addParam("ProjectId", project.getId())
|
||||
.addParam("Locale", ReportSettings.getPrintingLocale(null))
|
||||
.toAttach(project)
|
||||
.generate()
|
||||
.getFileLink();
|
||||
|
||||
response.setView(ActionView.define(name).add("html", fileLink).map());
|
||||
}
|
||||
|
||||
public void getPartnerData(ActionRequest request, ActionResponse response) {
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
Partner partner = project.getClientPartner();
|
||||
|
||||
if (partner != null) {
|
||||
|
||||
response.setValue("currency", partner.getCurrency());
|
||||
|
||||
response.setValue(
|
||||
"priceList",
|
||||
project.getClientPartner() != null
|
||||
? Beans.get(PartnerPriceListService.class)
|
||||
.getDefaultPriceList(project.getClientPartner(), PriceListRepository.TYPE_SALE)
|
||||
: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.businessproject.report.ITranslation;
|
||||
import com.axelor.apps.businessproject.service.ProjectFolderService;
|
||||
import com.axelor.apps.project.db.ProjectFolder;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.ResponseMessageType;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class ProjectFolderController {
|
||||
|
||||
public void printProjectsPlanificationAndCost(ActionRequest request, ActionResponse response)
|
||||
throws AxelorException {
|
||||
|
||||
ProjectFolder projectFolder = request.getContext().asType(ProjectFolder.class);
|
||||
String fileLink;
|
||||
String title;
|
||||
|
||||
try {
|
||||
fileLink =
|
||||
Beans.get(ProjectFolderService.class).printProjectsPlanificationAndCost(projectFolder);
|
||||
title = I18n.get(ITranslation.PROJECT_REPORT_TITLE_FOR_PLANIFICATION_AND_COST);
|
||||
response.setView(ActionView.define(title).add("html", fileLink).map());
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e, ResponseMessageType.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public void printProjectsFinancialReport(ActionRequest request, ActionResponse response)
|
||||
throws AxelorException {
|
||||
|
||||
ProjectFolder projectFolder = request.getContext().asType(ProjectFolder.class);
|
||||
String fileLink;
|
||||
String title;
|
||||
|
||||
try {
|
||||
fileLink = Beans.get(ProjectFolderService.class).printProjectFinancialReport(projectFolder);
|
||||
title = I18n.get(ITranslation.PROJECT_REPORT_TITLE_FOR_FINANCIAL);
|
||||
response.setView(ActionView.define(title).add("html", fileLink).map());
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e, ResponseMessageType.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.base.db.Batch;
|
||||
import com.axelor.apps.base.db.repo.BatchRepository;
|
||||
import com.axelor.apps.businessproject.db.InvoicingProject;
|
||||
import com.axelor.apps.businessproject.db.ProjectInvoicingAssistantBatch;
|
||||
import com.axelor.apps.businessproject.db.repo.ProjectInvoicingAssistantBatchRepository;
|
||||
import com.axelor.apps.businessproject.service.batch.ProjectInvoicingAssistantBatchService;
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ProjectInvoicingAssistantBatchController {
|
||||
|
||||
public void actionUpdateTask(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
ProjectInvoicingAssistantBatch projectInvoicingAssistantBatch =
|
||||
request.getContext().asType(ProjectInvoicingAssistantBatch.class);
|
||||
|
||||
projectInvoicingAssistantBatch =
|
||||
Beans.get(ProjectInvoicingAssistantBatchRepository.class)
|
||||
.find(projectInvoicingAssistantBatch.getId());
|
||||
|
||||
Batch batch =
|
||||
Beans.get(ProjectInvoicingAssistantBatchService.class)
|
||||
.updateTask(projectInvoicingAssistantBatch);
|
||||
response.setFlash(batch.getComments());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
} finally {
|
||||
response.setReload(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void showUpdatedTask(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Map<String, Object> values = new HashMap<String, Object>();
|
||||
values.put("field", "updatedTaskSet");
|
||||
values.put("title", I18n.get("Updated tasks"));
|
||||
values.put("model", TeamTask.class.getName());
|
||||
values.put("grid", "business-project-team-task-grid");
|
||||
values.put("form", "team-task-form");
|
||||
|
||||
this.showRecords(request, response, values);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void showUpdatedTimesheetLine(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Map<String, Object> values = new HashMap<String, Object>();
|
||||
values.put("field", "updatedTimesheetLineSet");
|
||||
values.put("title", I18n.get("Updated timesheet lines"));
|
||||
values.put("model", TimesheetLine.class.getName());
|
||||
values.put("grid", "timesheet-line-project-grid");
|
||||
values.put("form", "timesheet-line-project-form");
|
||||
|
||||
this.showRecords(request, response, values);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void actionGenerateInvoicingProject(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
ProjectInvoicingAssistantBatch projectInvoicingAssistantBatch =
|
||||
request.getContext().asType(ProjectInvoicingAssistantBatch.class);
|
||||
|
||||
projectInvoicingAssistantBatch =
|
||||
Beans.get(ProjectInvoicingAssistantBatchRepository.class)
|
||||
.find(projectInvoicingAssistantBatch.getId());
|
||||
|
||||
Batch batch =
|
||||
Beans.get(ProjectInvoicingAssistantBatchService.class)
|
||||
.generateInvoicingProject(projectInvoicingAssistantBatch);
|
||||
|
||||
response.setFlash(batch.getComments());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
} finally {
|
||||
response.setReload(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void showGeneratedInvoicingProject(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Map<String, Object> values = new HashMap<String, Object>();
|
||||
values.put("field", "generatedInvoicingProjectSet");
|
||||
values.put("title", I18n.get("Generated invoicing projects"));
|
||||
values.put("model", InvoicingProject.class.getName());
|
||||
values.put("grid", "invoicing-project-grid");
|
||||
values.put("form", "invoicing-project-form");
|
||||
|
||||
this.showRecords(request, response, values);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void showRecords(
|
||||
ActionRequest request, ActionResponse response, Map<String, Object> values)
|
||||
throws ClassNotFoundException {
|
||||
|
||||
Batch batch = request.getContext().asType(Batch.class);
|
||||
batch = Beans.get(BatchRepository.class).find(batch.getId());
|
||||
|
||||
String ids =
|
||||
Beans.get(ProjectInvoicingAssistantBatchService.class)
|
||||
.getShowRecordIds(batch, values.get("field").toString());
|
||||
|
||||
response.setView(
|
||||
ActionView.define(values.get("title").toString())
|
||||
.model(values.get("model").toString())
|
||||
.add("grid", values.get("grid").toString())
|
||||
.add("form", values.get("form").toString())
|
||||
.domain("self.id IN (" + ids + ")")
|
||||
.map());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.PurchaseOrderLineProjectService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrderLine;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderLineRepository;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PurchaseOrderLineProjectController {
|
||||
|
||||
/**
|
||||
* Set project from context selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void setProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
project = Beans.get(ProjectRepository.class).find(project.getId());
|
||||
|
||||
setProject(request, response, project);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setProject(ActionRequest request, ActionResponse response, Project project) {
|
||||
|
||||
List<Map<String, Object>> purchaseOrderLineSet =
|
||||
(List<Map<String, Object>>) request.getContext().get("purchaseOrderLineSet");
|
||||
|
||||
if (purchaseOrderLineSet == null || purchaseOrderLineSet.isEmpty()) {
|
||||
response.setFlash(IExceptionMessage.LINES_NOT_SELECTED);
|
||||
} else {
|
||||
List<Long> lineIds =
|
||||
purchaseOrderLineSet
|
||||
.stream()
|
||||
.map(it -> Long.parseLong(it.get("id").toString()))
|
||||
.collect(Collectors.toList());
|
||||
Beans.get(PurchaseOrderLineProjectService.class).setProject(lineIds, project);
|
||||
response.setAttr("$purchaseOrderLineSet", "hidden", true);
|
||||
response.setAttr("addSelectedPOLinesBtn", "hidden", true);
|
||||
response.setAttr("unlinkSelectedPOLinesBtn", "hidden", true);
|
||||
response.setAttr("cancelManagePOLinesBtn", "hidden", true);
|
||||
response.setAttr("purchaseOrderLinePanel", "refresh", true);
|
||||
response.setAttr("purchaseOrderPanel", "refresh", true);
|
||||
response.setAttr("selectNewPOLinesBtn", "readonly", false);
|
||||
response.setAttr("managePOLinesBtn", "readonly", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove project from selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void unsetProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
setProject(request, response, null);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invert value of 'toInvoice' field and save the record
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
@Transactional
|
||||
public void updateToInvoice(ActionRequest request, ActionResponse response) {
|
||||
PurchaseOrderLineRepository purchaseOrderLineRepository =
|
||||
Beans.get(PurchaseOrderLineRepository.class);
|
||||
try {
|
||||
PurchaseOrderLine purchaseOrderLine = request.getContext().asType(PurchaseOrderLine.class);
|
||||
purchaseOrderLine = purchaseOrderLineRepository.find(purchaseOrderLine.getId());
|
||||
purchaseOrderLine.setToInvoice(!purchaseOrderLine.getToInvoice());
|
||||
purchaseOrderLineRepository.save(purchaseOrderLine);
|
||||
response.setValue("toInvoice", purchaseOrderLine.getToInvoice());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.purchase.db.PurchaseOrder;
|
||||
import com.axelor.apps.purchase.db.PurchaseOrderLine;
|
||||
import com.axelor.apps.purchase.db.repo.PurchaseOrderRepository;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class PurchaseOrderProjectController {
|
||||
|
||||
public void updateLines(ActionRequest request, ActionResponse response) throws AxelorException {
|
||||
PurchaseOrder purchaseOrder = request.getContext().asType(PurchaseOrder.class);
|
||||
purchaseOrder = Beans.get(PurchaseOrderRepository.class).find(purchaseOrder.getId());
|
||||
|
||||
for (PurchaseOrderLine orderLine : purchaseOrder.getPurchaseOrderLineList()) {
|
||||
orderLine.setProject(purchaseOrder.getProject());
|
||||
}
|
||||
response.setValue("purchaseOrderLineList", purchaseOrder.getPurchaseOrderLineList());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.SaleOrderLineProjectService;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.repo.ProjectRepository;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderLineRepository;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SaleOrderLineProjectController {
|
||||
|
||||
/**
|
||||
* Set project from context selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void setProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
|
||||
Project project = request.getContext().asType(Project.class);
|
||||
project = Beans.get(ProjectRepository.class).find(project.getId());
|
||||
|
||||
setProject(request, response, project);
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setProject(ActionRequest request, ActionResponse response, Project project) {
|
||||
List<Map<String, Object>> saleOrderLineSet =
|
||||
(List<Map<String, Object>>) request.getContext().get("salesOrderLineSet");
|
||||
if (saleOrderLineSet == null || saleOrderLineSet.isEmpty()) {
|
||||
response.setFlash(IExceptionMessage.LINES_NOT_SELECTED);
|
||||
} else {
|
||||
List<Long> lineIds =
|
||||
saleOrderLineSet
|
||||
.stream()
|
||||
.map(it -> Long.parseLong(it.get("id").toString()))
|
||||
.collect(Collectors.toList());
|
||||
Beans.get(SaleOrderLineProjectService.class).setProject(lineIds, project);
|
||||
response.setAttr("$salesOrderLineSet", "hidden", true);
|
||||
response.setAttr("addSelectedSOLinesBtn", "hidden", true);
|
||||
response.setAttr("unlinkSelectedSOLinesBtn", "hidden", true);
|
||||
response.setAttr("cancelManageSOLinesBtn", "hidden", true);
|
||||
response.setAttr("saleOrderLinePanel", "refresh", true);
|
||||
response.setAttr("saleOrderPanel", "refresh", true);
|
||||
response.setAttr("selectNewSOLinesBtn", "readonly", false);
|
||||
response.setAttr("manageSOLinesBtn", "readonly", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove project from selected lines
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void unsetProject(ActionRequest request, ActionResponse response) {
|
||||
|
||||
try {
|
||||
setProject(request, response, null);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invert value of 'toInvoice' field and save the record
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
@Transactional
|
||||
public void updateToInvoice(ActionRequest request, ActionResponse response) {
|
||||
SaleOrderLineRepository saleOrderLineRepository = Beans.get(SaleOrderLineRepository.class);
|
||||
try {
|
||||
SaleOrderLine saleOrderLine = request.getContext().asType(SaleOrderLine.class);
|
||||
saleOrderLine = saleOrderLineRepository.find(saleOrderLine.getId());
|
||||
saleOrderLine.setToInvoice(!saleOrderLine.getToInvoice());
|
||||
saleOrderLineRepository.save(saleOrderLine);
|
||||
response.setValue("toInvoice", saleOrderLine.getToInvoice());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.base.service.app.AppBaseService;
|
||||
import com.axelor.apps.businessproject.exception.IExceptionMessage;
|
||||
import com.axelor.apps.businessproject.service.projectgenerator.ProjectGeneratorFactory;
|
||||
import com.axelor.apps.project.db.Project;
|
||||
import com.axelor.apps.project.db.ProjectGeneratorType;
|
||||
import com.axelor.apps.sale.db.SaleOrder;
|
||||
import com.axelor.apps.sale.db.SaleOrderLine;
|
||||
import com.axelor.apps.sale.db.repo.SaleOrderRepository;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.axelor.exception.ResponseMessageType;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.meta.schema.actions.ActionView;
|
||||
import com.axelor.meta.schema.actions.ActionView.ActionViewBuilder;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.axelor.rpc.Context;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Singleton;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
|
||||
@Singleton
|
||||
public class SaleOrderProjectController {
|
||||
|
||||
private static final String CONTEXT_SHOW_RECORD = "_showRecord";
|
||||
|
||||
public void generateProject(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
SaleOrder saleOrder = request.getContext().asType(SaleOrder.class);
|
||||
saleOrder = Beans.get(SaleOrderRepository.class).find(saleOrder.getId());
|
||||
if (saleOrder.getSaleOrderLineList() == null || saleOrder.getSaleOrderLineList().isEmpty()) {
|
||||
response.setAlert(I18n.get(IExceptionMessage.SALE_ORDER_GENERATE_FILL_PROJECT_ERROR_2));
|
||||
return;
|
||||
}
|
||||
String generatorType = (String) request.getContext().get("_projectGeneratorType");
|
||||
LocalDateTime startDate = getElementStartDate(request.getContext());
|
||||
|
||||
ProjectGeneratorType projectGeneratorType = ProjectGeneratorType.valueOf(generatorType);
|
||||
|
||||
ProjectGeneratorFactory factory = ProjectGeneratorFactory.getFactory(projectGeneratorType);
|
||||
|
||||
Project project;
|
||||
if (projectGeneratorType.equals(ProjectGeneratorType.PROJECT_ALONE)) {
|
||||
project = factory.create(saleOrder);
|
||||
} else {
|
||||
project = factory.generate(saleOrder, startDate);
|
||||
}
|
||||
|
||||
response.setReload(true);
|
||||
response.setView(
|
||||
ActionView.define("Project")
|
||||
.model(Project.class.getName())
|
||||
.add("form", "project-form")
|
||||
.param("forceEdit", "true")
|
||||
.context(CONTEXT_SHOW_RECORD, String.valueOf(project.getId()))
|
||||
.map());
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e, ResponseMessageType.ERROR);
|
||||
response.setReload(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void fillProject(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
SaleOrder saleOrder = request.getContext().asType(SaleOrder.class);
|
||||
saleOrder = Beans.get(SaleOrderRepository.class).find(saleOrder.getId());
|
||||
if (saleOrder.getSaleOrderLineList() == null
|
||||
|| (saleOrder.getSaleOrderLineList() != null
|
||||
&& saleOrder.getSaleOrderLineList().isEmpty())) {
|
||||
response.setAlert(I18n.get(IExceptionMessage.SALE_ORDER_GENERATE_FILL_PROJECT_ERROR_2));
|
||||
return;
|
||||
}
|
||||
String generatorType = (String) request.getContext().get("_projectGeneratorType");
|
||||
LocalDateTime startDate = getElementStartDate(request.getContext());
|
||||
|
||||
ProjectGeneratorFactory factory =
|
||||
ProjectGeneratorFactory.getFactory(ProjectGeneratorType.valueOf(generatorType));
|
||||
ActionViewBuilder view = factory.fill(saleOrder.getProject(), saleOrder, startDate);
|
||||
|
||||
response.setReload(true);
|
||||
response.setView(view.map());
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
response.setReload(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateLines(ActionRequest request, ActionResponse response) throws AxelorException {
|
||||
SaleOrder saleOrder = request.getContext().asType(SaleOrder.class);
|
||||
saleOrder = Beans.get(SaleOrderRepository.class).find(saleOrder.getId());
|
||||
|
||||
for (SaleOrderLine orderLine : saleOrder.getSaleOrderLineList()) {
|
||||
orderLine.setProject(saleOrder.getProject());
|
||||
}
|
||||
response.setValue("saleOrderLineList", saleOrder.getSaleOrderLineList());
|
||||
}
|
||||
|
||||
private LocalDateTime getElementStartDate(Context context) {
|
||||
LocalDateTime date;
|
||||
String stringStartDate = (String) context.get("_elementStartDate");
|
||||
if (!Strings.isNullOrEmpty(stringStartDate)) {
|
||||
date = LocalDateTime.ofInstant(Instant.parse(stringStartDate), ZoneId.systemDefault());
|
||||
} else {
|
||||
date = Beans.get(AppBaseService.class).getTodayDate().atStartOfDay();
|
||||
}
|
||||
return date;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.businessproject.service.TeamTaskBusinessProjectService;
|
||||
import com.axelor.apps.project.db.TeamTaskCategory;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.axelor.team.db.TeamTask;
|
||||
import com.axelor.team.db.repo.TeamTaskRepository;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
|
||||
public class TeamTaskController {
|
||||
|
||||
@Inject private TeamTaskBusinessProjectService businessProjectService;
|
||||
|
||||
public void updateDiscount(ActionRequest request, ActionResponse response) {
|
||||
|
||||
TeamTask teamTask = request.getContext().asType(TeamTask.class);
|
||||
|
||||
if (teamTask.getProduct() == null || teamTask.getProject() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
teamTask = Beans.get(TeamTaskBusinessProjectService.class).updateDiscount(teamTask);
|
||||
|
||||
response.setValue("discountTypeSelect", teamTask.getDiscountTypeSelect());
|
||||
response.setValue("discountAmount", teamTask.getDiscountAmount());
|
||||
response.setValue("priceDiscounted", teamTask.getPriceDiscounted());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void compute(ActionRequest request, ActionResponse response) {
|
||||
TeamTask teamTask = request.getContext().asType(TeamTask.class);
|
||||
|
||||
try {
|
||||
teamTask = Beans.get(TeamTaskBusinessProjectService.class).compute(teamTask);
|
||||
response.setValue("priceDiscounted", teamTask.getPriceDiscounted());
|
||||
response.setValue("exTaxTotal", teamTask.getExTaxTotal());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invert value of 'toInvoice' field and save the record
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
@Transactional
|
||||
public void updateToInvoice(ActionRequest request, ActionResponse response) {
|
||||
TeamTaskRepository teamTaskRepository = Beans.get(TeamTaskRepository.class);
|
||||
try {
|
||||
TeamTask teamTask = request.getContext().asType(TeamTask.class);
|
||||
teamTask = teamTaskRepository.find(teamTask.getId());
|
||||
teamTask.setToInvoice(!teamTask.getToInvoice());
|
||||
teamTaskRepository.save(teamTask);
|
||||
response.setValue("toInvoice", teamTask.getToInvoice());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void onChangeCategory(ActionRequest request, ActionResponse response) {
|
||||
TeamTask task = request.getContext().asType(TeamTask.class);
|
||||
TeamTaskCategory teamTaskCategory = task.getTeamTaskCategory();
|
||||
task = businessProjectService.resetTeamTaskValues(task);
|
||||
if (teamTaskCategory != null) {
|
||||
task = businessProjectService.computeDefaultInformation(task);
|
||||
}
|
||||
|
||||
if (task.getInvoicingType() == TeamTaskRepository.INVOICING_TYPE_TIME_SPENT) {
|
||||
task.setToInvoice(true);
|
||||
}
|
||||
response.setValues(task);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 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.businessproject.web;
|
||||
|
||||
import com.axelor.apps.businessproject.service.TimesheetLineBusinessService;
|
||||
import com.axelor.apps.hr.db.TimesheetLine;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
|
||||
public class TimesheetLineBusinessController {
|
||||
|
||||
public void setDefaultToInvoice(ActionRequest request, ActionResponse response) {
|
||||
TimesheetLine timesheetLine = request.getContext().asType(TimesheetLine.class);
|
||||
timesheetLine =
|
||||
Beans.get(TimesheetLineBusinessService.class).getDefaultToInvoice(timesheetLine);
|
||||
response.setValue("toInvoice", timesheetLine.getToInvoice());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<csv-inputs xmlns="http://axelor.com/xml/ns/data-import"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/data-import http://axelor.com/xml/ns/data-import/data-import_5.2.xsd">
|
||||
|
||||
<input file="auth_permission.csv" separator=";" type="com.axelor.auth.db.Permission" search="self.name = :name" call="com.axelor.csv.script.ImportPermission:importPermissionToRole">
|
||||
<bind to="canRead" eval="can_read == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canWrite" eval="can_write == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canCreate" eval="can_create == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canRemove" eval="can_remove == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canExport" eval="can_export == 'x' ? 'true' : 'false'"/>
|
||||
</input>
|
||||
|
||||
<input file="base_appBusinessProject.csv" separator=";" type="com.axelor.apps.base.db.AppBusinessProject" call="com.axelor.csv.script.ImportApp:importApp">
|
||||
<bind column="dependsOn" to="dependsOnSet" search="self.code in :dependsOn" eval="dependsOn.split(',') as List"/>
|
||||
</input>
|
||||
|
||||
<input file="meta_helpEN.csv" separator=";" type="com.axelor.meta.db.MetaHelp">
|
||||
<bind to="language" eval="'en'" />
|
||||
<bind to="type" eval="'tooltip'" />
|
||||
<bind to="model" eval="com.axelor.inject.Beans.get(com.axelor.meta.db.repo.MetaModelRepository.class).findByName(object)?.getFullName()" column="object" />
|
||||
</input>
|
||||
|
||||
<input file="meta_helpFR.csv" separator=";" type="com.axelor.meta.db.MetaHelp">
|
||||
<bind to="language" eval="'fr'" />
|
||||
<bind to="type" eval="'tooltip'" />
|
||||
<bind to="model" eval="com.axelor.inject.Beans.get(com.axelor.meta.db.repo.MetaModelRepository.class).findByName(object)?.getFullName()" column="object" />
|
||||
</input>
|
||||
|
||||
<input file="meta_metaMenu.csv" separator=";" type="com.axelor.meta.db.MetaMenu" search="self.name = :name" update="true" />
|
||||
|
||||
<input file="meta_metaJsonField.csv" separator=";" type="com.axelor.meta.db.MetaJsonField"
|
||||
search="self.name = :name and self.model = :model and self.modelField = :modelField and self.jsonModel is null"
|
||||
call="com.axelor.studio.service.ImportService:importJsonField">
|
||||
<bind to="name" column="name"/>
|
||||
<bind to="title" column="title"/>
|
||||
<bind to="type" column="type"/>
|
||||
<bind to="model" column="model"/>
|
||||
<bind to="modelField" column="modelField"/>
|
||||
<bind to="targetModel" column="targetModel"/>
|
||||
<bind to="sequence" column="sequence"/>
|
||||
<bind to="onClick" column="onClick"/>
|
||||
<bind to="gridView" column="gridView"/>
|
||||
<bind to="formView" column="formView"/>
|
||||
<bind to="widgetAttrs" column="widgetAttrs"/>
|
||||
<bind to="showIf" column="showIf"/>
|
||||
</input>
|
||||
|
||||
</csv-inputs>
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
"name";"object";"can_read";"can_write";"can_create";"can_remove";"can_export";"condition";"conditionParams";"roleName"
|
||||
"perm.businessproject.all";"com.axelor.apps.businessproject.db.*";"x";"x";"x";"x";"x";;;"Admin"
|
||||
|
@ -0,0 +1,2 @@
|
||||
"name";"code";"installOrder";"description";"imagePath";"modules";"dependsOn";"sequence"
|
||||
"Job costing";"business-project";17;"Job costing";"app-business-project.png";"axelor-business-project";"project,employee,supplychain";12
|
||||
|
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
@ -0,0 +1,22 @@
|
||||
"module";"object";"view";"field";"help"
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"manualUnblock";"If a customer is blocked, you can manually unblock it by clicking on this check-box."
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"saleOrderSeq";"Internal reference number for the order, generated when the order is saved for the first time. "
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"priceList";"Enables to attach a price list to be used for this particular order. This field is automatically filled in if a price list is attached to the partner."
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"project";"Enables to select a project to which the order will be attached. This function, useful for business project management, will allow to invoice the order (when invoicing the business project), as well as other elements."
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"expectedRealisationDate";"Enables to specify an estimated payment date for the invoice, which will be generated from the order. "
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"hideDiscount";"Checkbox to check for not showing the details of the discounts on the printings of the quotations/orders."
|
||||
"axelor-business-project";"SaleOrder";"sale-order-template-form";"createOrder";"This button generates a new draft of customer quotation from the selected model. "
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"generateProjectOrder";"This option allows you to select a project on an order as part of the job costing management. The order will be attached to a business project, on which you can invoice the order lines."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"automaticProject";"If this option is enabled, a project will be automatically generated at each sales order confirmation."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"projectSaleOrderLines";"This option allows you to activate a project tab in the sale order lines, which will allow to select a business project and indicate whether the order line should be invoiced in the business project. It is therefore an essential option for invoicing order lines in a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"projectPurchaseOrderLines";"This option allows you to activate a project tab in the purchase order lines, which will allow to select a business project and indicate whether the order line should be invoiced in the business project. It is therefore an essential option for invoicing order lines in a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"projectInvoiceLines";"This option allows you to activate a project tab in the invoice lines, which will link the invoices to the business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"productInvoicingProject";"Allow to define a default invoicing product on business projects, when these are invoiced on a flat rate basis."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showPurchaseOrderLineRelatedToProject";"By enabling this option, you will display the purchase order lines attached to a business project, in the ""Related elements"" tab of a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showSaleOrderLineRelatedToProject";"By enabling this option, you will display the sale order lines attached to a business project, in the ""Related elements"" tab of a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showProductionOrderRelatedToProject";"By enabling this option, you will display the production orders attached to a business project, in the ""Related elements"" tab of a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showExpenseLineRelatedToProject";"By enabling this option, you will display the expenses attached to a business project, in the ""Related elements"" tab of a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showPurchaseInvoiceLineRelatedToProject";"By enabling this option, you will display the purchase invoice lines attached to a business project, in the ""Related elements"" tab of a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showSaleInvoiceLineRelatedToProject";"By enabling this option, you will display the sale invoice lines attached to a business project, in the ""Related elements"" tab of a business project."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"enableToInvoiceTimesheet";"This option allows invoicing of timesheets in business projects."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"enableToInvoiceExpense";"This option allows invoicing of expenses in business projects."
|
||||
|
@ -0,0 +1,22 @@
|
||||
"module";"object";"view";"field";"help"
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"manualUnblock";"Si un client est bloqué, vous pouvez si vous en avez les droits le débloquer manuellement en cliquant sur cette case."
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"saleOrderSeq";"Numéro de référence interne de la commande, celui-ci est généré lors de la première sauvegarde du la commande. "
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"priceList";"Permet d'associer une liste de prix à utiliser spécifiquement pour cette commande. Ce champ est rempli automatiquement si une liste de prix est rattachée au tiers. "
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"project";"Permet de sélectionner un projet auquel rattacher la commande. Cette fonction liée à la gestion par affaire permettra de facturer (lors de la facturation de l'affaire) la commande ainsi que d'autres éléments."
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"expectedRealisationDate";"Permet de renseigner une date estimée de paiment de la facture qui sera générée à partir de la commande. "
|
||||
"axelor-business-project";"SaleOrder";"sale-order-form";"hideDiscount";"Case à cocher permettant de ne pas faire apparaitre les informations détaillées des remises sur les impressions des devis/commandes."
|
||||
"axelor-business-project";"SaleOrder";"sale-order-template-form";"createOrder";"Bouton permettant de générer un nouveau devis client à l'état brouillon à partir du modèle sélectionné. "
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"generateProjectOrder";"Cette option permet va permettre de sélectionner un projet sur une commande dans le cadre de la facturation à l'affaire. La commande sera rattachée à une affaire, sur laquelle vous pourrez facturer les lignes de commande."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"automaticProject";"Si cette option est activée, un projet sera automatiquement généré à chaque confirmation de commande client."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"projectSaleOrderLines";"Cette option permet d'activer un onglet concernant les projets/affaires dans les lignes de commandes clients, qui va permettre de sélectionner une affaire et d'indiquer si la ligne de commande doit être facturée dans l'affaire. Il s'agit donc d'une option indispensable pour facturer des lignes de commandes dans une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"projectPurchaseOrderLines";"Cette option permet d'activer un onglet concernant les projets/affaires dans les lignes de commandes fournisseurs, qui va permettre de sélectionner une affaire et d'indiquer si la ligne de commande doit être facturée dans l'affaire. Il s'agit donc d'une option indispensable pour facturer des lignes de commandes dans une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"projectInvoiceLines";"Cette option permet d'activer un onglet concernant les projets/affaires dans les lignes de factures, qui va permettre de rattacher les factures aux affaires."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"productInvoicingProject";"Permet de définir un produit de facturation par défaut sur les affaires, quand celles-ci sont facturées au forfait."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showPurchaseOrderLineRelatedToProject";"En activant cette option, vous afficherez les lignes de commandes fournisseurs rattachées à une affaire, dans l'onglet ""Eléments rattachés"" d'une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showSaleOrderLineRelatedToProject";"En activant cette option, vous afficherez les lignes de commandes clients rattachées à une affaire, dans l'onglet ""Eléments rattachés"" d'une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showProductionOrderRelatedToProject";"En activant cette option, vous afficherez les ordres de production rattachés à une affaire, dans l'onglet ""Eléments rattachés"" d'une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showExpenseLineRelatedToProject";"En activant cette option, vous afficherez les notes de frais rattachées à une affaire, dans l'onglet ""Eléments rattachés"" d'une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showPurchaseInvoiceLineRelatedToProject";"En activant cette option, vous afficherez les lignes de factures fournisseurs rattachées à une affaire, dans l'onglet ""Eléments rattachés"" d'une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"showSaleInvoiceLineRelatedToProject";"En activant cette option, vous afficherez les lignes de factures clients rattachées à une affaire, dans l'onglet ""Eléments rattachés"" d'une affaire."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"enableToInvoiceTimesheet";"Cette option permet d'autoriser la facturation des feuilles de temps dans les affaires."
|
||||
"axelor-business-project";"AppBusinessProject";"app-business-project-config-form";"enableToInvoiceExpense";"Cette option permet d'autoriser la facturation des notes de frais dans les affaires."
|
||||
|
@ -0,0 +1,10 @@
|
||||
"name";"title";"type";"model";"modelField";"targetModel";"sequence";"onClick";"gridView";"formView";"widgetAttrs";"showIf"
|
||||
"updatedTaskSet";"Updated tasks";"many-to-many";"com.axelor.apps.base.db.Batch";"attrs";"com.axelor.team.db.TeamTask";0;;"business-project-team-task-grid";"team-task-form";"{""colSpan"": ""12""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 1"
|
||||
"taskSpacer";;"Spacer";"com.axelor.apps.base.db.Batch";"attrs";;1;;;;"{""colSpan"": ""12""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 1"
|
||||
"showUpdatedTaskBtn";"Show updated tasks";"Button";"com.axelor.apps.base.db.Batch";"attrs";;2;"action-project-invoicing-assistant-batch-method-show-task,close";;;"{""colSpan"": ""5""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 1"
|
||||
"updatedTimesheetLineSet";"Updated timesheet lines";"many-to-many";"com.axelor.apps.base.db.Batch";"attrs";"com.axelor.apps.hr.db.TimesheetLine";3;;"timesheet-line-project-grid";"timesheet-line-project-form";"{""colSpan"": ""12""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 1"
|
||||
"timesheetLineSpacer";;"Spacer";"com.axelor.apps.base.db.Batch";"attrs";;4;;;;"{""colSpan"": ""12""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 1"
|
||||
"showUpdatedTimesheetLineBtn";"Show updated timesheet lines";"Button";"com.axelor.apps.base.db.Batch";"attrs";;5;"action-project-invoicing-assistant-batch-method-show-timesheet-line,close";;;"{""colSpan"": ""5""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 1"
|
||||
"generatedInvoicingProjectSet";"Generated invoicing projects";"many-to-many";"com.axelor.apps.base.db.Batch";"attrs";"com.axelor.apps.businessproject.db.InvoicingProject";6;;"invoicing-project-grid";"invoicing-project-form";"{""colSpan"": ""12""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 2"
|
||||
"invProjectSpacer";;"Spacer";"com.axelor.apps.base.db.Batch";"attrs";;7;;;;"{""colSpan"": ""12""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 2"
|
||||
"showGeneratedInvoicingProjectBtn";"Show generated invoicing projects";"Button";"com.axelor.apps.base.db.Batch";"attrs";;8;"action-project-invoicing-assistant-batch-method-show-inv-project,close";;;"{""colSpan"": ""5""}";"$record.projectInvoicingAssistantBatch != null && $record.projectInvoicingAssistantBatch.actionSelect == 2"
|
||||
|
@ -0,0 +1,5 @@
|
||||
"name";"roles.name"
|
||||
"business-project-root";"Admin"
|
||||
"business-project-folder";"Admin"
|
||||
"business-project-all";"Admin"
|
||||
"invoicing-project-all";"Admin"
|
||||
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<csv-inputs xmlns="http://axelor.com/xml/ns/data-import"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/data-import http://axelor.com/xml/ns/data-import/data-import_5.2.xsd">
|
||||
|
||||
<input file="base_appBusinessProject.csv" separator=";" type="com.axelor.apps.base.db.AppBusinessProject" search="self.code = :code" update="true" />
|
||||
|
||||
<input file="account_accountConfig.csv" separator=";" type="com.axelor.apps.account.db.AccountConfig" search="self.importId = :importId" update="true"/>
|
||||
|
||||
</csv-inputs>
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
"importId";"displayTimesheetOnPrinting";"displayExpenseOnPrinting"
|
||||
1;true;true
|
||||
|
@ -0,0 +1,2 @@
|
||||
"code";"generateProjectOrder";"projectSaleOrderLines";"projectPurchaseOrderLines";"projectInvoiceLines";"productInvoicingProject.importId";"showPurchaseOrderLineRelatedToProject";"showSaleOrderLineRelatedToProject";"showExpenseLineRelatedToProject"
|
||||
"business-project";"true";"true";"true";"true";400;"true";"true";"true"
|
||||
|
@ -0,0 +1,2 @@
|
||||
"importId";"displayTimesheetOnPrinting";"displayExpenseOnPrinting"
|
||||
1;true;true
|
||||
|
@ -0,0 +1,2 @@
|
||||
"code";"generateProjectOrder";"projectSaleOrderLines";"projectPurchaseOrderLines";"projectInvoiceLines";"productInvoicingProject.importId";"showPurchaseOrderLineRelatedToProject";"showSaleOrderLineRelatedToProject";"showExpenseLineRelatedToProject"
|
||||
"business-project";"true";"true";"true";"true";400;"true";"true";"true"
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="account" package="com.axelor.apps.account.db"/>
|
||||
<entity name="AccountConfig" lang="java" cacheable="true">
|
||||
|
||||
<boolean name="displayTimesheetOnPrinting" title="Display timesheet lines on printing"/>
|
||||
<boolean name="displayExpenseOnPrinting" title="Display expense lines on printing"/>
|
||||
|
||||
<track>
|
||||
<field name="displayTimesheetOnPrinting" on="UPDATE"/>
|
||||
<field name="displayExpenseOnPrinting" on="UPDATE"/>
|
||||
</track>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="account" package="com.axelor.apps.account.db"/>
|
||||
|
||||
<entity name="AnalyticMoveLine" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="account" package="com.axelor.apps.account.db"/>
|
||||
|
||||
<entity name="AnalyticMoveLine" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Business project"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="base" package="com.axelor.apps.base.db"/>
|
||||
|
||||
<entity name="AppBusinessProject" lang="java" extends="App">
|
||||
|
||||
<many-to-one name="productInvoicingProject" ref="com.axelor.apps.base.db.Product" title="Default Invoicing Product for Projects"/>
|
||||
|
||||
<boolean name="showPurchaseOrderLineRelatedToProject" title="Show purchase order lines related to the project"/>
|
||||
<boolean name="showSaleOrderLineRelatedToProject" title="Show sale order lines related to the project" />
|
||||
<boolean name="showExpenseLineRelatedToProject" title="Show expense order lines related to the project" />
|
||||
<boolean name="showProductionOrderRelatedToProject" title="Show production orders related to the project" />
|
||||
<boolean name="showPurchaseInvoiceLineRelatedToProject" title="Show purchase invoice line related to the project"/>
|
||||
<boolean name="showSaleInvoiceLineRelatedToProject" title="Show sale invoice line related to the project"/>
|
||||
|
||||
<boolean name="enableToInvoiceTimesheet" title="Enable to invoice timesheet" />
|
||||
<boolean name="enableToInvoiceExpense" title="Enable to invoice expense" />
|
||||
|
||||
<boolean name="generateProjectOrder" title="Generate/Select Project for Order"/>
|
||||
<boolean name="automaticProject" title="Automatic Project"/>
|
||||
|
||||
<integer name="generatedElementTypeSelect" title="Generated element type" default="3" selection="business.project.config.generated.element.type"/>
|
||||
|
||||
<boolean name="projectSaleOrderLines" title="Project in Sale order lines"/>
|
||||
<boolean name="projectPurchaseOrderLines" title="Project in Purchase order lines"/>
|
||||
|
||||
<boolean name="projectInvoiceLines" title="Project in Invoice Lines"/>
|
||||
|
||||
<boolean name="enableTaskTemplatesByProduct" title="Enable task templates by product"/>
|
||||
|
||||
<string name="preTaskStatusSet" title="Status for invoice pre task tasks" selection="team.task.status"/>
|
||||
<string name="postTaskStatusSet" title="Status for invoice post task tasks" selection="team.task.status"/>
|
||||
<string name="exculdeTaskInvoicing" title="Exculde tasks for invoicing"/>
|
||||
|
||||
<track>
|
||||
<field name="productInvoicingProject" on="UPDATE"/>
|
||||
|
||||
<field name="showPurchaseOrderLineRelatedToProject" on="UPDATE"/>
|
||||
<field name="showSaleOrderLineRelatedToProject" on="UPDATE"/>
|
||||
<field name="showExpenseLineRelatedToProject" on="UPDATE"/>
|
||||
<field name="showProductionOrderRelatedToProject" on="UPDATE"/>
|
||||
<field name="showPurchaseInvoiceLineRelatedToProject" on="UPDATE"/>
|
||||
<field name="showSaleInvoiceLineRelatedToProject" on="UPDATE"/>
|
||||
|
||||
<field name="enableToInvoiceTimesheet" on="UPDATE"/>
|
||||
<field name="enableToInvoiceExpense" on="UPDATE"/>
|
||||
<field name="generateProjectOrder" on="UPDATE"/>
|
||||
<field name="automaticProject" on="UPDATE"/>
|
||||
<field name="generatedElementTypeSelect" on="UPDATE"/>
|
||||
<field name="projectSaleOrderLines" on="UPDATE"/>
|
||||
<field name="projectPurchaseOrderLines" on="UPDATE"/>
|
||||
<field name="projectInvoiceLines" on="UPDATE"/>
|
||||
<field name="enableTaskTemplatesByProduct" on="UPDATE"/>
|
||||
</track>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="base" package="com.axelor.apps.base.db"/>
|
||||
|
||||
<entity name="Batch" lang="java" sequential="true">
|
||||
|
||||
<!-- NOT DISPLAY -->
|
||||
<many-to-one name="projectInvoicingAssistantBatch" ref="com.axelor.apps.businessproject.db.ProjectInvoicingAssistantBatch"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="contract" package="com.axelor.apps.contract.db" />
|
||||
|
||||
<entity name="Contract" repository="abstract">
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project"/>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="account" package="com.axelor.apps.account.db"/>
|
||||
|
||||
<entity sequential="true" name="Invoice" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project" />
|
||||
<boolean name="displayTimesheetOnPrinting" title="Display timesheet lines on printing"/>
|
||||
<boolean name="displayExpenseOnPrinting" title="Display expense lines on printing"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="account" package="com.axelor.apps.account.db"/>
|
||||
|
||||
<entity name="InvoiceLine" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project" />
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="business-project" package="com.axelor.apps.businessproject.db"/>
|
||||
|
||||
<entity name="InvoicingProject" cacheable="true">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Business project"/>
|
||||
<many-to-many name="logTimesSet" ref="com.axelor.apps.hr.db.TimesheetLine" title="Log Times" />
|
||||
<many-to-many name="saleOrderLineSet" ref="com.axelor.apps.sale.db.SaleOrderLine" title="Sale order lines" />
|
||||
<many-to-many name="purchaseOrderLineSet" ref="com.axelor.apps.purchase.db.PurchaseOrderLine" title="Purchase order lines" />
|
||||
<many-to-many name="expenseLineSet" ref="com.axelor.apps.hr.db.ExpenseLine" title="Expense Lines" />
|
||||
<many-to-many name="projectSet" ref="com.axelor.apps.project.db.Project" title="Project" />
|
||||
<many-to-many name="teamTaskSet" ref="com.axelor.team.db.TeamTask" title="Tasks" />
|
||||
<integer name="logTimesSetPrioritySelect" selection="invoicing.project.priority.select" title="Log Times Priority" default="3"/>
|
||||
<integer name="saleOrderLineSetPrioritySelect" selection="invoicing.project.priority.select" title="Sale order lines Priority" default="1"/>
|
||||
<integer name="purchaseOrderLineSetPrioritySelect" selection="invoicing.project.priority.select" title="Purchase order lines Priority" default="2"/>
|
||||
<integer name="expenseLineSetPrioritySelect" selection="invoicing.project.priority.select" title="Expense Lines Priority" default="4"/>
|
||||
<integer name="projectSetPrioritySelect" selection="invoicing.project.priority.select" title="Project Priority" default="5"/>
|
||||
<integer name="teamTaskSetPrioritySelect" selection="invoicing.project.priority.select" title="Task Priority" default="6"/>
|
||||
<many-to-one name="invoice" ref="com.axelor.apps.account.db.Invoice" title="Invoice generated" />
|
||||
<date name="deadlineDate" title="Deadline"/>
|
||||
<string name="comments" title="Comments" large="true" />
|
||||
<boolean name="attachAnnexToInvoice" title="Attach the Annex to the invoice"/>
|
||||
<integer name="statusSelect" title="Status" selection="business.project.invoicing.project.status.select" default="1"/>
|
||||
|
||||
<extra-code>
|
||||
// STATUS SELECT
|
||||
public static final int STATUS_DRAFT = 1;
|
||||
public static final int STATUS_GENERATED = 2;
|
||||
public static final int STATUS_VALIDATED = 3;
|
||||
public static final int STATUS_VENTILATED = 4;
|
||||
public static final int STATUS_CANCELED = 5;
|
||||
</extra-code>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="business-project" package="com.axelor.apps.businessproject.db"/>
|
||||
|
||||
<entity name="ManualElement" cacheable="true">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project"/>
|
||||
<string name="title" title="Title" required="true"/>
|
||||
<date name="date" column="date_val" title="Date"/>
|
||||
<decimal name="turnover" title="Turnover W.T."/>
|
||||
<decimal name="cost" title="Cost W.T."/>
|
||||
<many-to-one name="currency" ref="com.axelor.apps.base.db.Currency" title="Currency"/>
|
||||
<integer name="typeSelect" title="Type" selection="business.project.manual.element.type.select" default="1"/>
|
||||
<string name="comments" title="Comments" large="true"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="base" package="com.axelor.apps.base.db"/>
|
||||
|
||||
<entity name="Partner" lang="java">
|
||||
|
||||
<integer name="chargeBackPurchaseSelect" title="Charging Back Purchases Type" selection="business.project.charging.back.purchases.select"/>
|
||||
<decimal name="chargeBackPurchase" title="% Charging Back Purhcases" default="100"/>
|
||||
|
||||
<extra-code><![CDATA[
|
||||
|
||||
// TYPE SELECT
|
||||
public static final int CHARGING_BACK_TYPE_IDENTICALLY = 1;
|
||||
public static final int CHARGING_BACK_TYPE_PRICE_LIST = 2;
|
||||
public static final int CHARGING_BACK_TYPE_PERCENTAGE = 3;
|
||||
|
||||
]]></extra-code>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="base" package="com.axelor.apps.base.db"/>
|
||||
|
||||
<entity name="Product">
|
||||
<many-to-many name="taskTemplateSet" ref="com.axelor.apps.project.db.TaskTemplate" title="Task templates"/>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="project" package="com.axelor.apps.project.db"/>
|
||||
|
||||
<entity name="Project" cacheable="true">
|
||||
|
||||
<many-to-one name="currency" ref="com.axelor.apps.base.db.Currency" title="Currency" massUpdate="true"/>
|
||||
<integer name="invoicingSequenceSelect" title="Invoicing sequence" selection="business.project.invoicing.sequence.select"/>
|
||||
<string name="invoicingComment" title="Invoicing comment" large="true" />
|
||||
<decimal name="totalSaleOrdersFinalized" title="Finalized Orders Total" readonly="true"/>
|
||||
<decimal name="totalSaleOrdersConfirmed" title="Confirmed Orders Total" readonly="true"/>
|
||||
<decimal name="totalSaleOrdersInvoiced" title="Invoiced Orders Total" readonly="true"/>
|
||||
<many-to-one name="priceList" ref="com.axelor.apps.base.db.PriceList" title="Price list"/>
|
||||
|
||||
<decimal name="totalPurchaseOrdersFinalized" title="Finalized Orders Total" readonly="true"/>
|
||||
<decimal name="totalPurchaseOrdersConfirmed" title="Confirmed Orders Total" readonly="true"/>
|
||||
<decimal name="totalPurchaseOrdersInvoiced" title="Invoiced Orders Total" readonly="true"/>
|
||||
|
||||
<decimal name="totalTimesPlanned" title="Planned Times Total" readonly="true"/>
|
||||
<decimal name="totalTimesRealised" title="Realised Times Total" readonly="true"/>
|
||||
|
||||
<decimal name="totalExpenses" title="ExpensesTotal" readonly="true"/>
|
||||
|
||||
<decimal name="totalEstimatedCosts" title="Estimated Costs Total" readonly="true"/>
|
||||
<decimal name="totalRealCosts" title="Real Costs Total" readonly="true"/>
|
||||
|
||||
<decimal name="totalProducedTurnOver" title="Produced Turnover" readonly="true"/>
|
||||
<decimal name="estimatedMargin" title="Estimated Margin" readonly="true"/>
|
||||
<decimal name="realTimesMargin" title="Real Margin (Time)" readonly="true"/>
|
||||
<decimal name="realInvoicingMargin" title="Real Margin (Invoicing)" readonly="true"/>
|
||||
|
||||
<one-to-many name="manualElementList" ref="com.axelor.apps.businessproject.db.ManualElement" title="Manual elements" mappedBy="project"/>
|
||||
|
||||
<boolean name="invoiced" readonly="true"/>
|
||||
<string name="unitOnPrinting" selection="hr.time.logging.preference.select" title="Invoicing unit"/>
|
||||
|
||||
<one-to-many name="purchaseOrderLineList" ref="com.axelor.apps.purchase.db.PurchaseOrderLine" title="Purchase order lines" mappedBy="project" orphanRemoval="false"/>
|
||||
<one-to-many name="saleOrderLineList" ref="com.axelor.apps.sale.db.SaleOrderLine" title="Sale order lines" mappedBy="project" orphanRemoval="false"/>
|
||||
<one-to-many name="expensesLineList" ref="com.axelor.apps.hr.db.ExpenseLine" title="Expense lines" mappedBy="project" orphanRemoval="false"/>
|
||||
<one-to-many name="invoiceLineList" ref="com.axelor.apps.account.db.InvoiceLine" title="Invoice lines" mappedBy="project" orphanRemoval="false"/>
|
||||
|
||||
<boolean name="isBusinessProject" title="Business project" />
|
||||
|
||||
<boolean name="toInvoice" title="To invoice"/>
|
||||
<boolean name="isInvoicingTimesheet" title="Invoicing timesheet"/>
|
||||
<boolean name="isInvoicingExpenses" title="Invoicing Expenses"/>
|
||||
<boolean name="isInvoicingPurchases" title="Invoicing Purchases"/>
|
||||
|
||||
<many-to-one name="customerAddress" title="Address" ref="com.axelor.apps.base.db.Address"/>
|
||||
<extra-code><![CDATA[
|
||||
|
||||
// TYPE SELECT
|
||||
public static final int INVOICING_SEQ_EMPTY = 0;
|
||||
public static final int INVOICING_SEQ_INVOICE_PRE_TASK = 1;
|
||||
public static final int INVOICING_SEQ_INVOICE_POST_TASK = 2;
|
||||
|
||||
public static final int TASK_PER_LINE_ALONE = 1;
|
||||
public static final int TASK_PER_LINE_PHASE = 2;
|
||||
public static final int TASK_PER_LINE_TASK = 3;
|
||||
]]></extra-code>
|
||||
|
||||
|
||||
</entity>
|
||||
|
||||
<enum name="ProjectGeneratorType">
|
||||
<item name="PROJECT_ALONE" title="Project alone"/>
|
||||
<item name="PHASE_BY_LINE" title="Phase by line"/>
|
||||
<item name="TASK_BY_LINE" title="Task by line"/>
|
||||
<item name="TASK_TEMPLATE" title="Tasks by product"/>
|
||||
</enum>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="business-project" package="com.axelor.apps.businessproject.db"/>
|
||||
|
||||
<entity name="ProjectInvoicingAssistantBatch" cacheable="true">
|
||||
|
||||
<!-- HEADER -->
|
||||
<string name="code" title="Code" namecolumn="true" unique="true"/>
|
||||
<integer name="actionSelect" title="Action" required="true" selection="project.invoicing.assistant.batch.action.select"/>
|
||||
<many-to-one name="company" ref="com.axelor.apps.base.db.Company" title="Company" />
|
||||
|
||||
<!-- OTHERS INFORMATIONS -->
|
||||
<string name="description" title="Description" large="true" />
|
||||
<one-to-many name="batchList" ref="com.axelor.apps.base.db.Batch" mappedBy="projectInvoicingAssistantBatch" title="Batches" />
|
||||
|
||||
<extra-code><![CDATA[
|
||||
|
||||
// ACTION TYPE
|
||||
public static final int ACTION_UPDATE_TASKS = 1;
|
||||
public static final int ACTION_GENERATE_INVOICING_PROJECT = 2;
|
||||
|
||||
]]></extra-code>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="project" package="com.axelor.apps.project.db"/>
|
||||
|
||||
<entity name="ProjectTemplate">
|
||||
<boolean name="isInvoicingExpenses" title="Invoicing Expenses"/>
|
||||
<boolean name="isInvoicingPurchases" title="Invoicing Purchases"/>
|
||||
<integer name="invoicingTypeSelect" selection="project.invoicing.type.select" title="Invoicing Type"/>
|
||||
<string name="invoicingComment" title="Invoicing comment" large="true"/>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="purchase" package="com.axelor.apps.purchase.db"/>
|
||||
|
||||
<entity name="PurchaseOrder" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project" />
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="purchase" package="com.axelor.apps.purchase.db"/>
|
||||
|
||||
<entity name="PurchaseOrderLine" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project"/>
|
||||
<boolean name="toInvoice" title="To invoice with project"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="purchase" package="com.axelor.apps.purchase.db"/>
|
||||
|
||||
<entity name="PurchaseRequest" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project" />
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="sale" package="com.axelor.apps.sale.db"/>
|
||||
|
||||
<entity name="SaleOrder" lang="java">
|
||||
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project" />
|
||||
<boolean name="toInvoiceViaTask" title="To invoice via task" default="false"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user