Hi I'm creating a list mass action, to export invoice data in a txt file. I'm struggeling to retrieve the products related to the invoice. items list is always empty.
do you have some exemple ?
regards
<?php
namespace Espo\Modules\EcrituresComptables\Services;
use Espo\Core\Exceptions\Error;
use Espo\ORM\EntityManager;
if (!defined('DS'))
define('DS', DIRECTORY_SEPARATOR);
if (!defined('ABSPATH'))
define('ABSPATH', dirname(__DIR__));
class ExportService
{
private const FILE = ABSPATH . DS . 'Assets' . DS . 'ecritures.txt';
private const JOURNAL = '1VT';
private const CODE_TVA = 4457140000;
public function __construct(private EntityManager $entityManager)
{
}
public function createExport(array $ids): mixed
{
$items = [];
if (empty($ids))
throw new Error("Aucune facture n'a été sélectionné");
foreach ($ids as $i => $id) {
$item = new \stdClass();
$addReturn = $i > 0;
$method = $i === 0 ? 'w' : 'a'; // overwrite on first then add
$invoice = $this->entityManager->getEntityById('Invoice', $id);
// todo: find products...
$item->type = $invoice->get('type');
$item->nrFacture = $invoice->get('number');
$item->dateFacture = str_replace('-', '', $invoice->get('dateInvoiced'));
$item->dateFinFacture = str_replace('-', '', $invoice->get('invoiceLastDatePay'));
$item->prixTTC = $invoice->get('grandTotalAmount');
$item->prixHT = $invoice->get('amount');
$item->prixTVA = $invoice->get('taxAmount');
$item->participant = $invoice->get('participantName');
if (!$this->writeFile($this->createEntries($item, $addReturn), $method)) {
throw new Error("Impossible d'écrire dans le fichier d'export");
}
$item->designationCommande = $invoice->get('designationCommande');
$item->totalConverted = (float)$invoice->get('grandTotalAmountConverted');
$items[] = $item;
}
return $items;
}
private function createEntries(object $item, bool $addReturn = false): string
{
$entries = [];
if (!empty($item->prixTTC)) {
$entries[] = $this->createEntry($item, 'TTC');
}
if (!empty($item->prixHT)) {
$entries[] = $this->createEntry($item, 'HT');
}
if (!empty($item->prixTVA)) {
$entries[] = $this->createEntry($item, 'TVA');
}
if (empty($entries))
return '';
return ($addReturn ? "\n" : '') . implode("\n", $entries);
}
private function createEntry(object $item, $priceType = 'TTC'): string
{
$priceType = strtoupper($priceType);
if (!in_array($priceType, ['TTC', 'HT', 'TVA'])) {
throw new Error("Impossible de créer l'entrée");
}
$tab = "\t";
$type = $priceType === 'TTC' ? 'D' : 'C'; // débit ou crédit
$code = '';
switch ($priceType) {
case 'TTC':
$code = '{code_client}';
break;
case 'HT':
if ($item->type === 'SOIREE')
$code = 7060100000;
if ($item->type === 'JNFDM' || $item->type === 'CONVENTION')
$code = 7069000000;
break;
case 'TVA':
$code = self::CODE_TVA;
break;
}
$entry = self::JOURNAL . $item->dateFacture . $item->dateFinFacture;
$entry .= $item->nrFacture . $code . ' ';
$entry .= $item->nrFacture . ' - ' . $item->participant . $tab;
$entry .= number_format($item->{'prix' . $priceType}, 2, '.', '');
$entry .= $type . $item->nrFacture . $tab . $item->participant;
return $entry;
}
private function writeFile(string $content, string $method = 'a'): bool
{
if (!file_exists(self::FILE))
$method = 'a';
$file = fopen(self::FILE, $method);
fwrite($file, $content);
return fclose($file);
}
public function getFile(): string
{
return self::FILE;
}
}
namespace Espo\Modules\EcrituresComptables\Controllers;
use Espo\Core\Api\Request;
use Espo\Core\Api\Response;
use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\NotFound;
use Espo\Entities\User;
use Espo\Modules\EcrituresComptables\Services\ExportSe rvice;
class MainController
{
private ExportService $exportService;
private User $user;
/**
* @throws Forbidden
*/
public function __construct(ExportService $exportService, User $user)
{
$this->exportService = $exportService;
$this->user = $user;
if (
!$this->user->isAdmin() &&
!$this->user->isRegular() &&
!$this->user->isPortal() &&
!$this->user->isApi()
) {
throw new Forbidden();
}
}
/**
* POST api/v1/EcrituresComptables/export
*
* @throws Forbidden
* @throws Error
*/
public function postActionExport(Request $request, Response $response): array
{
if (!$this->user->isAdmin() && !$this->user->isApi())
throw new Forbidden();
$data = $request->getParsedBody(); // payload
$ids = $data->params->ids;
$items = $this->exportService->createExport($ids);
return [
'success' => true,
'msg' => '',
'data' => $items
];
}
/**
* GET api/v1/EcrituresComptables/download
*
* @throws Forbidden
* @throws Error
*/
public function getActionDownload(Request $request, Response $response)
{
if (!$this->user->isAdmin() && !$this->user->isApi())
throw new Forbidden();
$file = $this->exportService->getFile();
if (!file_exists($file))
throw new Error("Le fichier d'export n'a pas été trouvé");
//Define header information
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Cache-Control: no-cache, must-revalidate");
header("Expires: 0");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . filesize($file));
header('Pragma: public');
//Clear system output buffer
flush();
//Read the size of the file
readfile($file);
die();
}
}
$entity->loadItemListField();
$items = $entity->get('itemList');
Comment