render fixes, minor bug fixes

This commit is contained in:
Dennis Eichhorn 2022-03-05 17:03:46 +01:00
parent 09914eaf74
commit fdeb84d072
10 changed files with 466 additions and 97 deletions

View File

@ -33,5 +33,19 @@
"lang": "de"
}
]
},
{
"type": "type",
"name": "original",
"l11n": [
{
"title": "Original",
"lang": "en"
},
{
"title": "Original",
"lang": "de"
}
]
}
]

View File

@ -44,6 +44,7 @@ class Media
$media = \Modules\Media\Admin\Installer::installExternal($app, ['path' => __DIR__ . '/Media.install.json']);
$preivewType = (int) \reset($media['type'][0]);
$originalType = (int) \reset($media['type'][1]);
$setting = new Setting();
SettingMapper::create()->execute(
@ -56,5 +57,17 @@ class Media
'Billing'
)
);
$setting = new Setting();
SettingMapper::create()->execute(
$setting->with(
0,
SettingsEnum::ORIGINAL_MEDIA_TYPE,
(string) $originalType,
'\\d+',
null,
'Billing'
)
);
}
}

View File

@ -98,7 +98,7 @@
"uri": "{/prefix}purchase/bill/archive",
"target": "self",
"icon": null,
"order": 1,
"order": 5,
"from": "Billing",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 1005105001,
@ -113,7 +113,22 @@
"uri": "{/prefix}purchase/bill/create?{?}",
"target": "self",
"icon": null,
"order": 5,
"order": 10,
"from": "Billing",
"permission": { "permission": 4, "type": null, "element": null },
"parent": 1005105001,
"children": []
},
{
"id": 1005105401,
"pid": "/purchase/bill",
"type": 3,
"subtype": 1,
"name": "Upload",
"uri": "{/prefix}purchase/bill/upload?{?}",
"target": "self",
"icon": null,
"order": 15,
"from": "Billing",
"permission": { "permission": 4, "type": null, "element": null },
"parent": 1005105001,

View File

@ -1,4 +1,5 @@
<?php
/**
* Karaka
*
@ -10,6 +11,7 @@
* @version 1.0.0
* @link https://karaka.app
*/
declare(strict_types=1);
namespace Modules\Billing\Controller;
@ -19,19 +21,30 @@ use Modules\Billing\Models\Bill;
use Modules\Billing\Models\BillElement;
use Modules\Billing\Models\BillElementMapper;
use Modules\Billing\Models\BillMapper;
use Modules\Billing\Models\BillStatus;
use Modules\Billing\Models\BillTransferType;
use Modules\Billing\Models\BillTypeMapper;
use Modules\Billing\Models\SettingsEnum;
use Modules\ClientManagement\Models\ClientMapper;
use Modules\ItemManagement\Models\ItemMapper;
use Modules\Media\Models\PathSettings;
use Modules\Media\Models\UploadStatus;
use Modules\SupplierManagement\Models\SupplierMapper;
use phpOMS\Ai\Ocr\Tesseract\TesseractOcr;
use phpOMS\Autoloader;
use phpOMS\Image\Skew;
use phpOMS\Image\Thresholding;
use phpOMS\Localization\Money;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\HttpResponse;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\NotificationLevel;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Model\Message\FormValidation;
use phpOMS\System\SystemUtils;
use phpOMS\Uri\HttpUri;
use phpOMS\Utils\StringUtils;
use phpOMS\Views\View;
/**
@ -44,6 +57,73 @@ use phpOMS\Views\View;
*/
final class ApiController extends Controller
{
/**
* Api method to update a bill
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiBillUpdate(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
if (!empty($val = $this->validateBillUpdate($request))) {
$response->set($request->uri->__toString(), new FormValidation($val));
$response->header->status = RequestStatusCode::R_400;
return;
}
$old = clone BillMapper::get()->where('id', (int) $request->getData('bill'));
$new = $this->updateBillFromRequest($request, $response, $data);
$this->updateModel($request->header->account, $old, $new, BillMapper::class, 'bill', $request->getOrigin());
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Bill', 'Bill successfully created.', $new);
}
/**
* Method to validate bill creation from request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateBillUpdate(RequestAbstract $request): array
{
$val = [];
if (($val['bill'] = empty($request->getData('bill')))) {
return $val;
}
return [];
}
/**
* Method to create a bill from request.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return Bill
*
* @since 1.0.0
*/
public function updateBillFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null): Bill
{
/** @var Bill $bill */
$bill = BillMapper::get()->where('id', (int) $request->getData('bill'))->execute();
return $bill;
}
/**
* Api method to create a bill
*
@ -57,7 +137,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function apiBillCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
public function apiBillCreate(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
if (!empty($val = $this->validateBillCreate($request))) {
$response->set($request->uri->__toString(), new FormValidation($val));
@ -87,7 +167,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function createBillFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null) : Bill
public function createBillFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null): Bill
{
$account = null;
if ($request->getData('client') !== null) {
@ -113,6 +193,7 @@ final class ApiController extends Controller
$bill = new Bill();
$bill->createdBy = new NullAccount($request->header->account);
$bill->type = $billType;
$bill->setStatus((int) ($request->getData('status') ?? BillStatus::ACTIVE));
$bill->numberFormat = $billType->numberFormat;
$bill->billTo = $request->getData('billto')
?? ($account->profile->account->name1 . (!empty($account->profile->account->name2) ? ', ' . $account->profile->account->name2 : '')); // @todo: use defaultInvoiceAddress or mainAddress. also consider to use billto1, billto2, billto3 (for multiple lines e.g. name2, fao etc.)
@ -136,11 +217,10 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
private function validateBillCreate(RequestAbstract $request) : array
private function validateBillCreate(RequestAbstract $request): array
{
$val = [];
if (($val['client/customer'] = (empty($request->getData('client')) && empty($request->getData('supplier'))))
) {
if (($val['client/supplier'] = (empty($request->getData('client')) && empty($request->getData('supplier'))))) {
return $val;
}
@ -160,7 +240,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function apiMediaAddToBill(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
public function apiMediaAddToBill(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
if (!empty($val = $this->validateMediaAddToBill($request))) {
$response->set($request->uri->__toString(), new FormValidation($val));
@ -169,6 +249,9 @@ final class ApiController extends Controller
return;
}
$bill = BillMapper::get()->where('id', (int) $request->getData('bill'))->execute();
$path = $this->createBillDir($bill);
$uploaded = [];
if (!empty($uploadedFiles = $request->getFiles() ?? [])) {
$uploaded = $this->app->moduleManager->get('Media')->uploadFiles(
@ -176,16 +259,21 @@ final class ApiController extends Controller
[],
$uploadedFiles,
$request->header->account,
__DIR__ . '/../../../Modules/Media/Files/Modules/Editor',
'/Modules/Editor',
__DIR__ . '/../../../Modules/Media/Files' . $path,
$path,
type: $request->getData('type') ?? null,
pathSettings: PathSettings::FILE_PATH
);
foreach ($uploaded as $media) {
$this->createModelRelation(
$request->header->account,
$request->getData('bill'),
$bill->getId(),
$media->getId(),
BillMapper::class, 'media', '', $request->getOrigin()
BillMapper::class,
'media',
'',
$request->getOrigin()
);
}
}
@ -194,9 +282,12 @@ final class ApiController extends Controller
foreach ($mediaFiles as $media) {
$this->createModelRelation(
$request->header->account,
$request->getData('bill'),
$bill->getId(),
$media,
BillMapper::class, 'media', '', $request->getOrigin()
BillMapper::class,
'media',
'',
$request->getOrigin()
);
}
}
@ -207,6 +298,15 @@ final class ApiController extends Controller
]);
}
private function createBillDir(Bill $bill): string
{
return '/Modules/Billing/Bills/'
. $bill->createdAt->format('Y') . '/'
. $bill->createdAt->format('m') . '/'
. $bill->createdAt->format('d') . '/'
. $bill->getId();
}
/**
* Method to validate bill creation from request
*
@ -216,10 +316,10 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
private function validateMediaAddToBill(RequestAbstract $request) : array
private function validateMediaAddToBill(RequestAbstract $request): array
{
$val = [];
if (($val['media'] = empty($request->getData('media')) && empty($request->getFiles()))
if (($val['media'] = (empty($request->getData('media')) && empty($request->getFiles())))
|| ($val['bill'] = empty($request->getData('bill')))
) {
return $val;
@ -241,7 +341,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function apiBillElementCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
public function apiBillElementCreate(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
if (!empty($val = $this->validateBillElementCreate($request))) {
$response->set($request->uri->__toString(), new FormValidation($val));
@ -272,7 +372,7 @@ final class ApiController extends Controller
* @since 1.0.0
* @todo in the database the customer localized version should be stored because this is the version which went out
*/
public function createBillElementFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null) : BillElement
public function createBillElementFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null): BillElement
{
$element = new BillElement();
$element->bill = (int) $request->getData('bill');
@ -315,7 +415,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function updateBillWithBillElement(Bill $bill, BillElement $element, int $type = 1) : Bill
public function updateBillWithBillElement(Bill $bill, BillElement $element, int $type = 1): Bill
{
if ($type === 1) {
$bill->netSales->add($element->totalSalesPriceNet);
@ -334,11 +434,10 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
private function validateBillElementCreate(RequestAbstract $request) : array
private function validateBillElementCreate(RequestAbstract $request): array
{
$val = [];
if (($val['bill'] = empty($request->getData('bill')))
) {
if (($val['bill'] = empty($request->getData('bill')))) {
return $val;
}
@ -358,7 +457,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function apiBillPdfArchiveCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
public function apiBillPdfArchiveCreate(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
Autoloader::addPath(__DIR__ . '/../../../Resources/');
@ -376,10 +475,8 @@ final class ApiController extends Controller
$template = $bill->type->template;
$pdfDir = __DIR__ . '/../../../Modules/Media/Files/Modules/Billing/Bills/'
. $bill->createdAt->format('Y') . '/'
. $bill->createdAt->format('m') . '/'
. $bill->createdAt->format('d') . '/';
$path = $this->createBillDir($bill);;
$pdfDir = __DIR__ . '/../../../Modules/Media/Files' . $path;
$status = !\is_dir($pdfDir) ? \mkdir($pdfDir, 0755, true) : true;
if ($status === false) {
@ -394,11 +491,11 @@ final class ApiController extends Controller
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/' . \substr($template->getSourceByName('bill.pdf.php')->getPath(), 0, -8), 'pdf.php');
$view->setData('bill', $bill);
$view->setData('path', $pdfDir . $request->getData('bill') . '.pdf');
$view->setData('path', $pdfDir . '/' . $request->getData('bill') . '.pdf');
$pdf = $view->build();
if (!\is_file($pdfDir . $request->getData('bill') . '.pdf')) {
if (!\is_file($pdfDir . '/' . $request->getData('bill') . '.pdf')) {
$response->header->status = RequestStatusCode::R_400;
return;
@ -410,14 +507,11 @@ final class ApiController extends Controller
'name' => $request->getData('bill') . '.pdf',
'path' => $pdfDir,
'filename' => $request->getData('bill') . '.pdf',
'size' => \filesize($pdfDir . $request->getData('bill') . '.pdf'),
'size' => \filesize($pdfDir . '/' . $request->getData('bill') . '.pdf'),
'extension' => 'pdf',
],
$request->header->account,
'/Modules/Billing/Bills/'
. $bill->createdAt->format('Y') . '/'
. $bill->createdAt->format('m') . '/'
. $bill->createdAt->format('d'),
$path,
$previewType
);
@ -425,7 +519,10 @@ final class ApiController extends Controller
$request->header->account,
$bill->getId(),
$media->getId(),
BillMapper::class, 'media', '', $request->getOrigin()
BillMapper::class,
'media',
'',
$request->getOrigin()
);
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'PDF', 'Bill Pdf successfully created.', $media);
@ -444,7 +541,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function apiBillPdfCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
public function apiBillPdfCreate(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
}
@ -461,7 +558,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
if (!empty($val = $this->validateNoteCreate($request))) {
$response->set('bill_note_create', new FormValidation($val));
@ -470,7 +567,10 @@ final class ApiController extends Controller
return;
}
$request->setData('virtualpath', '/Modules/Billing/Bills/' . $request->getData('id'), true);
/** @var Bill $bill */
$bill = BillMapper::get()->where('id', (int) $request->getData('id'))->execute();
$request->setData('virtualpath', $this->createBillDir($bill), true);
$this->app->moduleManager->get('Editor')->apiEditorCreate($request, $response, $data);
if ($response->header->status !== RequestStatusCode::R_200) {
@ -490,14 +590,146 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
private function validateNoteCreate(RequestAbstract $request) : array
private function validateNoteCreate(RequestAbstract $request): array
{
$val = [];
if (($val['id'] = empty($request->getData('id')))
) {
if (($val['id'] = empty($request->getData('id')))) {
return $val;
}
return [];
}
/**
* Api method to create bill files
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiSupplierBillUpload(RequestAbstract $request, ResponseAbstract $response, $data = null): void
{
$originalType = (int) ($request->getData('type') ?? $this->app->appSettings->get(
names: SettingsEnum::ORIGINAL_MEDIA_TYPE,
module: self::NAME
)->content);
$purchaseTransferType = BillTypeMapper::get()
->where('transferType', BillTransferType::PURCHASE)
->limit(1)
->execute();
$files = $request->getFiles();
foreach ($files as $file) {
// Create default bill
$billRequest = new HttpRequest(new HttpUri(''));
$billRequest->header->account = $request->header->account;
$billRequest->header->l11n = $request->header->l11n;
$billRequest->setData('supplier', 1); // @todo: make suppleir 1 = unknown supplier
$billRequest->setData('status', BillStatus::UNPARSED);
$billRequest->setData('type', $purchaseTransferType->getId());
$billResponse = new HttpResponse();
$billResponse->header->l11n = $response->header->l11n;
$this->apiBillCreate($billRequest, $billResponse, $data);
$billId = $billResponse->get('')['response']->getId();
// Upload and assign document to bill
$mediaRequest = new HttpRequest();
$mediaRequest->header->account = $request->header->account;
$mediaRequest->header->l11n = $request->header->l11n;
$mediaRequest->addFile($file);
$mediaResponse = new HttpResponse();
$mediaResponse->header->l11n = $response->header->l11n;
$mediaRequest->setData('bill', $billId);
$mediaRequest->setData('type', $originalType);
$this->apiMediaAddToBill($mediaRequest, $mediaResponse, $data);
$uploaded = $mediaResponse->get('')['response']['upload'];
$in = \reset($uploaded)->getAbsolutePath();
if (!\is_file($in)) {
throw new \Exception();
}
// Extract text from document
$text = '';
$tmpDir = \sys_get_temp_dir();
// Is PDF
if (StringUtils::endsWith($in, '.pdf')) {
SystemUtils::runProc('/usr/bin/pdftotext', '-layout ' . \escapeshellarg($in) . ' ' . \escapeshellarg($out = \tempnam($tmpDir, 'pdf_')));
$text = \file_get_contents($out);
\unlink($out);
}
// Is image or PDF couldn't get parsed to text
if (\strlen($text) < 256) {
SystemUtils::runProc('/usr/bin/pdftoppm', '-jpeg -r 300 ' . \escapeshellarg($in) . ' ' . \escapeshellarg($out = \tempnam($tmpDir, 'pdf_')));
$files = \glob($out . '*');
if ($files === false) {
return;
}
foreach ($files as $file) {
if (
!StringUtils::endsWith($file, '.jpg')
&& !StringUtils::endsWith($file, '.png')
&& !StringUtils::endsWith($file, '.gif')
) {
continue;
}
/* Too slow
Thresholding::integralThresholding($file, $file);
Skew::autoRotate($file, $file, 10);
*/
SystemUtils::runProc(__DIR__ . '/../../../cOMS/Tools/InvoicePreprocessing/App', \escapeshellarg($file) . ' ' . \escapeshellarg($file));
$ocr = new TesseractOcr();
$text = $ocr->parseImage($file);
\unlink($file);
}
}
// @todo: Parse text and analyze text structure
// Update bill with parsed text
$billRequest = new HttpRequest();
$billRequest->header->account = $request->header->account;
$billRequest->header->l11n = $request->header->l11n;
$billRequest->setData('bill', $billId);
$billRequest->setData('supplier', 1);
$billResponse = new HttpResponse();
$billResponse->header->l11n = $response->header->l11n;
$this->apiBillUpdate($billRequest, $billResponse, $data);
// Create internal document
$billResponse = new HttpResponse();
$billRequest = new HttpRequest(new HttpUri(''));
$billRequest->header->account = $request->header->account;
$billRequest->setData('bill', $billId);
$this->apiBillPdfArchiveCreate($billRequest, $billResponse);
// @todo: Start workflow for bill, if a workflow is defined for bill uploading
}
}
}

View File

@ -14,6 +14,7 @@ declare(strict_types=1);
namespace Modules\Billing\Controller;
use Modules\Billing\Models\BillTransferType;
use Modules\Billing\Models\PurchaseBillMapper;
use Modules\Billing\Models\SalesBillMapper;
use Modules\Billing\Models\SettingsEnum;
@ -60,6 +61,7 @@ final class BackendController extends Controller
->with('type')
->with('type/l11n')
->with('client')
->where('type/transferType', BillTransferType::SALES)
->sort('id', OrderType::DESC)
->limit(25);
@ -206,19 +208,37 @@ final class BackendController extends Controller
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill-list');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response));
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005105001, $request, $response));
$mapperQuery = PurchaseBillMapper::getAll()
->with('type')
->with('type/l11n')
->with('supplier')
->where('type/transferType', BillTransferType::PURCHASE)
->sort('id', OrderType::DESC)
->limit(25);
if ($request->getData('ptype') === 'p') {
$view->setData('bills',
PurchaseBillMapper::getAll()->where('id', (int) ($request->getData('id') ?? 0), '<')->limit(25)->execute()
$mapperQuery
->where('id', (int) ($request->getData('id') ?? 0), '<')
->where('supplier', null, '!=')
->where('type/l11n/language', $response->getLanguage())
->execute()
);
} elseif ($request->getData('ptype') === 'n') {
$view->setData('bills',
PurchaseBillMapper::getAll()->where('id', (int) ($request->getData('id') ?? 0), '>')->limit(25)->execute()
$mapperQuery->where('id', (int) ($request->getData('id') ?? 0), '>')
->where('supplier', null, '!=')
->where('type/l11n/language', $response->getLanguage())
->execute()
);
} else {
$view->setData('bills',
PurchaseBillMapper::getAll()->where('id', 0, '>')->limit(25)->execute()
$mapperQuery->where('id', 0, '>')
->where('supplier', null, '!=')
->where('type/l11n/language', $response->getLanguage())
->execute()
);
}
@ -243,7 +263,12 @@ final class BackendController extends Controller
$view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response));
$bill = PurchaseBillMapper::get()->where('id', (int) $request->getData('id'))->execute();
$bill = PurchaseBillMapper::get()
->with('elements')
->with('media')
->with('notes')
->where('id', (int) $request->getData('id'))
->execute();
$view->setData('bill', $bill);
@ -254,6 +279,13 @@ final class BackendController extends Controller
$view->setData('previewType', $previewType);
$originalType = (int) $this->app->appSettings->get(
names: SettingsEnum::ORIGINAL_MEDIA_TYPE,
module: self::NAME
)->content;
$view->setData('originalType', $originalType);
return $view;
}

View File

@ -35,4 +35,6 @@ abstract class BillStatus extends Enum
public const DONE = 8;
public const DRAFT = 16;
public const UNPARSED = 32;
}

View File

@ -26,5 +26,9 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class SettingsEnum extends Enum
{
public const PREVIEW_MEDIA_TYPE = '1005100001_1';
public const PREVIEW_MEDIA_TYPE = '1005100001_1'; // internally generated preview
public const ORIGINAL_MEDIA_TYPE = '1005100001_2'; // original document (mostly supplier invoice/delivery note)
}

View File

@ -15,28 +15,28 @@ declare(strict_types=1);
return ['Billing' => [
'Address' => 'Address',
'Addresses' => 'Addresses',
'Africa' => '',
'Africa' => 'Africa',
'AlreadyPaid' => 'Already Paid',
'America' => '',
'Analyse' => '',
'Articles' => '',
'Asia' => '',
'Attribute' => '',
'BaseTime' => '',
'America' => 'America',
'Analyse' => 'Analyse',
'Articles' => 'Articles',
'Asia' => 'Asia',
'Attribute' => 'Attribute',
'BaseTime' => 'Base time',
'Bills' => 'Bills',
'Bonus' => 'Bonus',
'CIS' => '',
'CIS' => 'CIS',
'Cashback' => 'Cash Back',
'City' => 'City',
'Client' => 'Client',
'ClientID' => 'Client ID',
'ComparisonTime' => '',
'ComparisonTime' => 'Comparison time',
'Confirmation' => 'Confirmation',
'Country' => 'Country',
'Created' => 'Created',
'CreditCard' => 'CreditCard',
'CreditNote' => 'Credit Note',
'Customers' => '',
'Customers' => 'Customers',
'Date' => 'Date',
'Delivery' => 'Delivery',
'DeliveryNote' => 'Delivery Note',
@ -44,10 +44,10 @@ return ['Billing' => [
'Discount' => 'Discount',
'DiscountP' => 'Discount %',
'Due' => 'Due',
'Europe' => '',
'Filter' => '',
'Europe' => 'Europe',
'Filter' => 'Filter',
'Freightage' => 'Freightage',
'General' => '',
'General' => 'General',
'Gross' => 'Gross',
'Invoice' => 'Invoice',
'Invoices' => 'Invoices',
@ -60,7 +60,7 @@ return ['Billing' => [
'Name' => 'Name',
'Net' => 'Net',
'Offer' => 'Offer',
'Other' => '',
'Other' => 'Other',
'Payment' => 'Payment',
'Postal' => 'Postal',
'Prepaid' => 'Prepaid',
@ -69,9 +69,9 @@ return ['Billing' => [
'Profit' => 'Profit',
'Quantity' => 'Quantity',
'Recipient' => 'Recipient',
'Region' => '',
'Rep' => '',
'Sales' => '',
'Region' => 'Region',
'Rep' => 'Rep.',
'Sales' => 'Sales',
'Select' => 'Select',
'Shipment' => 'Shipment',
'Source' => 'Source',
@ -82,7 +82,7 @@ return ['Billing' => [
'Total' => 'Total',
'Type' => 'Type',
'Upload' => 'Upload',
'Value' => '',
'Value' => 'Value',
'Variation' => 'Variation',
'Zip' => 'Zip',
]];

View File

@ -26,6 +26,10 @@ echo $this->getData('nav')->render(); ?>
<table id="billList" class="default sticky">
<thead>
<tr>
<td><label class="checkbox" for="iBillSelect-0">
<input type="checkbox" id="iBillSelect-0" name="billselect">
<span class="checkmark"></span>
</label>
<td><?= $this->getHtml('ID', '0', '0'); ?>
<label for="billList-sort-1">
<input type="radio" name="billList-sort" id="billList-sort-1">
@ -50,7 +54,7 @@ echo $this->getData('nav')->render(); ?>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td><?= $this->getHtml('ClientID'); ?>
<td><?= $this->getHtml('SupplierID'); ?>
<label for="billList-sort-5">
<input type="radio" name="billList-sort" id="billList-sort-5">
<i class="sort-asc fa fa-chevron-up"></i>
@ -62,7 +66,7 @@ echo $this->getData('nav')->render(); ?>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td class="wf-100"><?= $this->getHtml('Client'); ?>
<td class="wf-100"><?= $this->getHtml('Supplier'); ?>
<label for="billList-sort-7">
<input type="radio" name="billList-sort" id="billList-sort-7">
<i class="sort-asc fa fa-chevron-up"></i>
@ -123,8 +127,8 @@ echo $this->getData('nav')->render(); ?>
<i class="filter fa fa-filter"></i>
</label>
<td><?= $this->getHtml('Net'); ?>
<label for="billList-sort-17">
<input type="radio" name="billList-sort" id="billList-sort-17">
<label for="billList-sort-7">
<input type="radio" name="billList-sort" id="billList-sort-7">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="billList-sort-18">
@ -134,18 +138,6 @@ echo $this->getData('nav')->render(); ?>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td><?= $this->getHtml('Profit'); ?>
<label for="billList-sort-21">
<input type="radio" name="billList-sort" id="billList-sort-21">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="billList-sort-22">
<input type="radio" name="billList-sort" id="billList-sort-22">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td><?= $this->getHtml('Created'); ?>
<label for="billList-sort-23">
<input type="radio" name="billList-sort" id="billList-sort-23">
@ -159,25 +151,30 @@ echo $this->getData('nav')->render(); ?>
<i class="filter fa fa-filter"></i>
</label>
<tbody>
<?php $count = 0; foreach ($bills as $key => $value) :
<?php $count = 0;
foreach ($bills as $key => $value) :
++$count;
$url = UriFactory::build('{/prefix}purchase/bill?{?}&id=' . $value->getId());
?>
<tr data-href="<?= $url; ?>">
<td><label class="checkbox" for="iBillSelect-<?= $key; ?>">
<input type="checkbox" id="iBillSelect-<?= $key; ?>" name="billselect">
<span class="checkmark"></span>
</label>
<td><a href="<?= $url; ?>"><?= $value->getNumber(); ?></a>
<td><a href="<?= $url; ?>"><?= $value->type->getL11n(); ?></a>
<td><a href="<?= $url; ?>"><?= $value->client->number; ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($value->billTo); ?></a>
<td><a href="<?= $url; ?>"><?= $value->billAddress; ?></a>
<td><a class="content" href="<?= $supplier = UriFactory::build('{/prefix}purchase/supplier/profile?{?}&id=' . $value->supplier->getId()); ?>"><?= $value->supplier->number; ?></a>
<td><a class="content" href="<?= $supplier; ?>"><?= $this->printHtml($value->billTo); ?></a>
<td><a href="<?= $url;
?>"><?= $value->billAddress; ?></a>
<td><a href="<?= $url; ?>"><?= $value->billZip; ?></a>
<td><a href="<?= $url; ?>"><?= $value->billCity; ?></a>
<td><a href="<?= $url; ?>"><?= $value->billCountry; ?></a>
<td><a href="<?= $url; ?>"><?= $value->net->getCurrency(); ?></a>
<td><a href="<?= $url; ?>"><?= $value->profit->getCurrency(); ?></a>
<td><a href="<?= $url; ?>"><?= $value->netSales->getCurrency(); ?></a>
<td><a href="<?= $url; ?>"><?= $value->createdAt->format('Y-m-d'); ?></a>
<?php endforeach; ?>
<?php if ($count === 0) : ?>
<tr><td colspan="11" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<tr><td colspan="12" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>

View File

@ -12,8 +12,13 @@
*/
declare(strict_types=1);
use Modules\Media\Models\NullMedia;
use phpOMS\System\File\FileUtils;
use phpOMS\Uri\UriFactory;
// Media helper functions (e.g. file icon generator)
include __DIR__ . '/../../../Media/Theme/Backend/template-functions.php';
/**
* @var \phpOMS\Views\View $this
*/
@ -21,7 +26,11 @@ use phpOMS\Uri\UriFactory;
$bill = $this->getData('bill');
$elements = $bill->getElements();
$billPdf = $bill->getMediaByType('bill');
$previewType = $this->getData('previewType');
$originalType = $this->getData('originalType');
$billPdf = $bill->getFileByType($previewType);
$original = $bill->getFileByType($originalType);
$media = $bill->getMedia();
echo $this->getData('nav')->render(); ?>
@ -31,9 +40,10 @@ echo $this->getData('nav')->render(); ?>
<li><label for="c-tab-1"><?= $this->getHtml('Invoice'); ?></label></li>
<li><label for="c-tab-2"><?= $this->getHtml('Items'); ?></label></li>
<li><label for="c-tab-3"><?= $this->getHtml('Preview'); ?></label></li>
<li><label for="c-tab-4"><?= $this->getHtml('Payment'); ?></label></li>
<li><label for="c-tab-5"><?= $this->getHtml('Media'); ?></label></li>
<li><label for="c-tab-6"><?= $this->getHtml('Logs'); ?></label></li>
<li><label for="c-tab-4"><?= $this->getHtml('Original'); ?></label></li>
<li><label for="c-tab-5"><?= $this->getHtml('Payment'); ?></label></li>
<li><label for="c-tab-6"><?= $this->getHtml('Media'); ?></label></li>
<li><label for="c-tab-7"><?= $this->getHtml('Logs'); ?></label></li>
</ul>
</div>
<div class="tab-content">
@ -179,9 +189,9 @@ echo $this->getData('nav')->render(); ?>
</table>
<div class="portlet-foot">
<?= $this->getHtml('Freightage'); ?>: 0.00 -
<?= $this->getHtml('Net'); ?>: <?= $bill->net->getCurrency(); ?> -
<?= $this->getHtml('Net'); ?>: <?= $bill->netSales->getCurrency(); ?> -
<?= $this->getHtml('Tax'); ?>: 0.00 -
<?= $this->getHtml('Total'); ?>: <?= $bill->gross->getCurrency(); ?>
<?= $this->getHtml('Total'); ?>: <?= $bill->grossSales->getCurrency(); ?>
</div>
</div>
</div>
@ -193,13 +203,29 @@ echo $this->getData('nav')->render(); ?>
<div class="col-xs-12">
<section id="mediaFile" class="portlet">
<div class="portlet-body">
<iframe style="min-height: 600px;" data-form="iUiSettings" data-name="iframeHelper" id="iHelperFrame" src="<?= UriFactory::build('{/backend}Resources/mozilla/Pdf/web/viewer.html?{?}&file=' . ($billPdf->isAbsolute ? '' : '/../../../../') . $billPdf->getPath()); ?>" allowfullscreen></iframe>
<?php if (!($billPdf instanceof NullMedia)) : ?>
<iframe style="min-height: 600px;" data-form="iUiSettings" data-name="iframeHelper" id="iHelperFrame" src="<?= UriFactory::build('{/backend}Resources/mozilla/Pdf/web/viewer.html{?}&file=' . \urlencode(($billPdf->isAbsolute ? '' : '/../../../../') . $billPdf->getPath())); ?>" allowfullscreen></iframe>
<?php endif; ?>
</div>
</section>
</div>
</div>
</div>
<input type="radio" id="c-tab-4" name="tabular-2">
<div class="tab">
<div class="row">
<div class="col-xs-12">
<section id="mediaFile" class="portlet">
<div class="portlet-body">
<?php if (!($original instanceof NullMedia)) : ?>
<iframe style="min-height: 600px;" data-form="iUiSettings" data-name="iframeHelper" id="iHelperFrame" src="<?= UriFactory::build('{/backend}Resources/mozilla/Pdf/web/viewer.html{?}&file=' . (($original->isAbsolute ? '' : '/../../../../') . $original->getPath())); ?>" allowfullscreen></iframe>
<?php endif; ?>
</div>
</section>
</div>
</div>
</div>
<input type="radio" id="c-tab-5" name="tabular-2">
<div class="tab">
<div class="row">
<div class="col-xs-12 col-md-6 col-lg-4">
@ -238,7 +264,7 @@ echo $this->getData('nav')->render(); ?>
</div>
</div>
</div>
<input type="radio" id="c-tab-5" name="tabular-2">
<input type="radio" id="c-tab-6" name="tabular-2">
<div class="tab">
<div class="row">
<div class="col-xs-12 col-md-6 col-lg-4">
@ -258,9 +284,43 @@ echo $this->getData('nav')->render(); ?>
</div>
</section>
</div>
<div class="col-xs-12 col-md-6 col-lg-8">
<div class="portlet">
<div class="portlet-head"><?= $this->getHtml('Media'); ?><i class="fa fa-download floatRight download btn"></i></div>
<table class="default" id="invoice-item-list">
<thead>
<tr>
<td>
<td>
<td class="wf-100"><?= $this->getHtml('Name'); ?>
<td><?= $this->getHtml('Type'); ?>
<tbody>
<?php foreach ($media as $file) :
$url = $file->extension === 'collection'
? UriFactory::build('{/prefix}media/list?path=' . \rtrim($file->getVirtualPath(), '/') . '/' . $file->name)
: UriFactory::build('{/prefix}media/single?id=' . $file->getId()
. '&path={?path}' . (
$file->getId() === 0
? '/' . $file->name
: ''
)
);
$icon = $fileIconFunction(FileUtils::getExtensionType($file->extension));
?>
<tr data-href="<?= $url; ?>">
<td>
<td data-label="<?= $this->getHtml('Type'); ?>"><a href="<?= $url; ?>"><i class="fa fa-<?= $this->printHtml($icon); ?>"></i></a>
<td><a href="<?= $url; ?>"><?= $file->name; ?></a>
<td><a href="<?= $url; ?>"><?= $file->extension; ?></a>
<?php endforeach; ?>
</table>
</div>
</div>
</div>
</div>
<input type="radio" id="c-tab-6" name="tabular-2">
<input type="radio" id="c-tab-7" name="tabular-2">
<div class="tab">
<div class="row">
<div class="col-xs-12">