bug fixes

This commit is contained in:
Dennis Eichhorn 2023-12-08 21:52:33 +00:00
parent 71cd6a9a9e
commit c750e20fa3
16 changed files with 93 additions and 71 deletions

View File

@ -73,7 +73,7 @@ $topPos = $pdf->getY();
// Set up default bill template // Set up default bill template
$billTypeName = \strtoupper($bill->type->getL11n()); $billTypeName = \strtoupper($bill->type->getL11n());
// @todo: depending on amount of lines, there is a solution (html, or use backtracking of tcpdf) // @todo depending on amount of lines, there is a solution (html, or use backtracking of tcpdf)
// Address // Address
$pdf->setY(50); $pdf->setY(50);
@ -144,7 +144,7 @@ $pdf->MultiCell(
. ($bill->billDate?->format('Y-m-d') ?? '0') . "\n" . ($bill->billDate?->format('Y-m-d') ?? '0') . "\n"
. ($bill->performanceDate?->format('Y-m-d') ?? '0') . "\n" . ($bill->performanceDate?->format('Y-m-d') ?? '0') . "\n"
. $bill->accountNumber . "\n" . $bill->accountNumber . "\n"
. '' . "\n" /* @todo: implement customer / supplier reference as string */ . '' . "\n" /* @todo implement customer / supplier reference as string */
. ($bill->billDate?->format('Y-m-d') ?? '0'), /* Consider to add dueDate in addition */ . ($bill->billDate?->format('Y-m-d') ?? '0'), /* Consider to add dueDate in addition */
0, 'L' 0, 'L'
); );
@ -184,7 +184,7 @@ $first = true;
// Data // Data
$fill = false; $fill = false;
foreach($lines as $line) { foreach($lines as $line) {
// @todo: add support for empty lines (row = line) // @todo add support for empty lines (row = line)
if (/*$row === null || */$first || $pdf->getY() > $pdf->getPageHeight() - 40) { if (/*$row === null || */$first || $pdf->getY() > $pdf->getPageHeight() - 40) {
$pdf->setFillColor(255, 162, 7); $pdf->setFillColor(255, 162, 7);
$pdf->setTextColor(255); $pdf->setTextColor(255);
@ -274,7 +274,7 @@ $pdf->Ln();
$tempY2 = $pdf->getY(); $tempY2 = $pdf->getY();
// @todo: fix payment terms // @todo fix payment terms
$pdf->setTextColor(0); $pdf->setTextColor(0);
$pdf->setFont('helvetica', 'B', 8); $pdf->setFont('helvetica', 'B', 8);
$pdf->setY($tempY); $pdf->setY($tempY);
@ -284,7 +284,7 @@ $pdf->setFont('helvetica', '', 8);
$pdf->Write(0, $bill->paymentText, '', false, 'L', false, 0, false, false, 0); $pdf->Write(0, $bill->paymentText, '', false, 'L', false, 0, false, false, 0);
$pdf->Ln(); $pdf->Ln();
// @todo: fix terms // @todo fix terms
$pdf->setFont('helvetica', 'B', 8); $pdf->setFont('helvetica', 'B', 8);
$pdf->Write(0, $lang[$pdf->language]['Terms'] . ': ' . $pdf->attributes['terms'], '', false, 'L', false, 0, false, false, 0); $pdf->Write(0, $lang[$pdf->language]['Terms'] . ': ' . $pdf->attributes['terms'], '', false, 'L', false, 0, false, false, 0);
$pdf->Ln(); $pdf->Ln();

View File

@ -326,8 +326,8 @@ final class Installer extends InstallerAbstract
/** @var \Modules\Billing\Controller\ApiController $module */ /** @var \Modules\Billing\Controller\ApiController $module */
$module = $app->moduleManager->getModuleInstance('Billing'); $module = $app->moduleManager->getModuleInstance('Billing');
// @todo: allow multiple alternative bill templates // @todo allow multiple alternative bill templates
// @todo: implement ordering of templates // @todo implement ordering of templates
foreach ($types as $type) { foreach ($types as $type) {
$response = new HttpResponse(); $response = new HttpResponse();

View File

@ -377,7 +377,7 @@ final class ApiAttributeController extends Controller
* *
* @api * @api
* *
* @todo: implement * @todo Implement API function
* *
* @since 1.0.0 * @since 1.0.0
*/ */
@ -448,7 +448,7 @@ final class ApiAttributeController extends Controller
*/ */
public function apiBillAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void public function apiBillAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{ {
// @todo: I don't think values can be deleted? Only Attributes // @todo I don't think values can be deleted? Only Attributes
// However, It should be possible to remove UNUSED default values // However, It should be possible to remove UNUSED default values
// either here or other function? // either here or other function?
// if (!empty($val = $this->validateAttributeValueDelete($request))) { // if (!empty($val = $this->validateAttributeValueDelete($request))) {

View File

@ -24,6 +24,7 @@ use Modules\Billing\Models\BillStatus;
use Modules\Billing\Models\BillTypeMapper; use Modules\Billing\Models\BillTypeMapper;
use Modules\Billing\Models\NullBill; use Modules\Billing\Models\NullBill;
use Modules\Billing\Models\NullBillElement; use Modules\Billing\Models\NullBillElement;
use Modules\Billing\Models\PermissionCategory;
use Modules\Billing\Models\SettingsEnum; use Modules\Billing\Models\SettingsEnum;
use Modules\ClientManagement\Models\Client; use Modules\ClientManagement\Models\Client;
use Modules\ClientManagement\Models\ClientMapper; use Modules\ClientManagement\Models\ClientMapper;
@ -38,6 +39,7 @@ use Modules\Messages\Models\EmailMapper;
use Modules\SupplierManagement\Models\NullSupplier; use Modules\SupplierManagement\Models\NullSupplier;
use Modules\SupplierManagement\Models\Supplier; use Modules\SupplierManagement\Models\Supplier;
use Modules\SupplierManagement\Models\SupplierMapper; use Modules\SupplierManagement\Models\SupplierMapper;
use phpOMS\Account\PermissionType;
use phpOMS\Application\ApplicationAbstract; use phpOMS\Application\ApplicationAbstract;
use phpOMS\Autoloader; use phpOMS\Autoloader;
use phpOMS\Localization\ISO4217CharEnum; use phpOMS\Localization\ISO4217CharEnum;
@ -216,12 +218,12 @@ final class ApiBillController extends Controller
*/ */
public function createBaseBill(Client | Supplier $account, RequestAbstract $request) : Bill public function createBaseBill(Client | Supplier $account, RequestAbstract $request) : Bill
{ {
// @todo: validate vat before creation for clients // @todo validate vat before creation for clients
$bill = new Bill(); $bill = new Bill();
$bill->createdBy = new NullAccount($request->header->account); $bill->createdBy = new NullAccount($request->header->account);
$bill->unit = $account->unit ?? $this->app->unitId; $bill->unit = $account->unit ?? $this->app->unitId;
$bill->billDate = new \DateTime('now'); // @todo: Date of payment $bill->billDate = new \DateTime('now'); // @todo Date of payment
$bill->performanceDate = $request->getDataDateTime('performancedate') ?? new \DateTime('now'); // @todo: Date of payment $bill->performanceDate = $request->getDataDateTime('performancedate') ?? new \DateTime('now'); // @todo Date of payment
$bill->accountNumber = $account->number; $bill->accountNumber = $account->number;
$bill->setStatus($request->getDataInt('status') ?? BillStatus::DRAFT); $bill->setStatus($request->getDataInt('status') ?? BillStatus::DRAFT);
@ -237,7 +239,7 @@ final class ApiBillController extends Controller
$bill->supplier = $account; $bill->supplier = $account;
} }
// @todo: use bill and shipping address instead of main address if available // @todo use bill and shipping address instead of main address if available
$bill->billTo = $request->getDataString('billto') ?? $account->account->name1; $bill->billTo = $request->getDataString('billto') ?? $account->account->name1;
$bill->billAddress = $request->getDataString('billaddress') ?? $account->mainAddress->address; $bill->billAddress = $request->getDataString('billaddress') ?? $account->mainAddress->address;
$bill->billCity = $request->getDataString('billtocity') ?? $account->mainAddress->city; $bill->billCity = $request->getDataString('billtocity') ?? $account->mainAddress->city;
@ -517,7 +519,7 @@ final class ApiBillController extends Controller
*/ */
public function apiMediaRemoveFromBill(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void public function apiMediaRemoveFromBill(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{ {
// @todo: check that it is not system generated media! // @todo check that it is not system generated media!
if (!empty($val = $this->validateMediaRemoveFromBill($request))) { if (!empty($val = $this->validateMediaRemoveFromBill($request))) {
$response->header->status = RequestStatusCode::R_400; $response->header->status = RequestStatusCode::R_400;
$this->createInvalidDeleteResponse($request, $response, $val); $this->createInvalidDeleteResponse($request, $response, $val);
@ -539,8 +541,8 @@ final class ApiBillController extends Controller
->execute(); ->execute();
if (\count($billCollection) !== 1) { if (\count($billCollection) !== 1) {
// @todo: For some reason there are multiple collections with the same virtual path? // @todo For some reason there are multiple collections with the same virtual path?
// @todo: check if this is the correct way to handle it or if we need to make sure that it is a collection // @todo check if this is the correct way to handle it or if we need to make sure that it is a collection
return; return;
} }
@ -571,7 +573,7 @@ final class ApiBillController extends Controller
if ($referenceCount === 0) { if ($referenceCount === 0) {
// Is not used anywhere else -> remove from db and file system // Is not used anywhere else -> remove from db and file system
// @todo: remove media types from media // @todo remove media types from media
$this->deleteModel($request->header->account, $media, MediaMapper::class, 'bill_media', $request->getOrigin()); $this->deleteModel($request->header->account, $media, MediaMapper::class, 'bill_media', $request->getOrigin());
@ -678,11 +680,11 @@ final class ApiBillController extends Controller
$element = $this->createBillElementFromRequest($request, $response, $old, $data); $element = $this->createBillElementFromRequest($request, $response, $old, $data);
$this->createModel($request->header->account, $element, BillElementMapper::class, 'bill_element', $request->getOrigin()); $this->createModel($request->header->account, $element, BillElementMapper::class, 'bill_element', $request->getOrigin());
// @todo: handle stock transaction here // @todo handle stock transaction here
// @todo: if transaction fails don't update below and send warning to user // @todo if transaction fails don't update below and send warning to user
// @todo: however mark transaction as reserved and only update when bill is finalized!!! // @todo however mark transaction as reserved and only update when bill is finalized!!!
// @todo: in BillElementUpdate do the same // @todo in BillElementUpdate do the same
$new = clone $old; $new = clone $old;
$new->addElement($element); $new->addElement($element);
@ -725,7 +727,7 @@ final class ApiBillController extends Controller
$element->bill = new NullBill($bill->id); $element->bill = new NullBill($bill->id);
// discounts // discounts
// @todo: implement a addDiscount function // @todo implement a addDiscount function
/* /*
if ($request->getData('discount_percentage') !== null) { if ($request->getData('discount_percentage') !== null) {
} }
@ -768,7 +770,7 @@ final class ApiBillController extends Controller
*/ */
public function apiMediaRender(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void public function apiMediaRender(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{ {
// @todo: check if has permission // @todo check if has permission
$this->app->moduleManager->get('Media', 'Api')->apiMediaExport($request, $response, ['ignorePermission' => true]); $this->app->moduleManager->get('Media', 'Api')->apiMediaExport($request, $response, ['ignorePermission' => true]);
} }
@ -937,7 +939,7 @@ final class ApiBillController extends Controller
->where('id', $request->getDataInt('bill') ?? 0) ->where('id', $request->getDataInt('bill') ?? 0)
->execute(); ->execute();
// @todo: This is stupid to do twice but I need to get the langauge. // @todo This is stupid to do twice but I need to get the langauge.
// For the future it should just be a join on the bill langauge!!! // For the future it should just be a join on the bill langauge!!!
// The problem is the where here is a model where and not a query // The problem is the where here is a model where and not a query
// builder where meaning it is always considered a value and not a column. // builder where meaning it is always considered a value and not a column.
@ -1006,7 +1008,7 @@ final class ApiBillController extends Controller
$view->data['defaultAssets'] = $defaultAssets; $view->data['defaultAssets'] = $defaultAssets;
$view->data['bill'] = $bill; $view->data['bill'] = $bill;
// @todo: add bill data such as company name bank information, ..., etc. // @todo add bill data such as company name bank information, ..., etc.
$pdf = $view->render(); $pdf = $view->render();
@ -1050,7 +1052,7 @@ final class ApiBillController extends Controller
); );
// Send bill via email // Send bill via email
// @todo: maybe not all bill types, and bill status (e.g. deleted should not be sent) // @todo maybe not all bill types, and bill status (e.g. deleted should not be sent)
$client = ClientMapper::get() $client = ClientMapper::get()
->with('account') ->with('account')
->with('attributes') ->with('attributes')
@ -1223,8 +1225,8 @@ final class ApiBillController extends Controller
/** @var \Modules\Billing\Models\Bill $old */ /** @var \Modules\Billing\Models\Bill $old */
$old = BillMapper::get()->where('id', (int) $request->getData('id'))->execute(); $old = BillMapper::get()->where('id', (int) $request->getData('id'))->execute();
// @todo: check if bill can be deleted // @todo check if bill can be deleted
// @todo: adjust stock transfer // @todo adjust stock transfer
$new = $this->deleteBillFromRequest($request, clone $old); $new = $this->deleteBillFromRequest($request, clone $old);
$this->updateModel($request->header->account, $old, $new, BillMapper::class, 'bill', $request->getOrigin()); $this->updateModel($request->header->account, $old, $new, BillMapper::class, 'bill', $request->getOrigin());
@ -1255,7 +1257,7 @@ final class ApiBillController extends Controller
* *
* @return array<string, bool> * @return array<string, bool>
* *
* @todo: implement * @todo Implement API validation function
* *
* @since 1.0.0 * @since 1.0.0
*/ */
@ -1294,8 +1296,8 @@ final class ApiBillController extends Controller
/** @var BillElement $old */ /** @var BillElement $old */
$old = BillElementMapper::get()->where('id', (int) $request->getData('id'))->execute(); $old = BillElementMapper::get()->where('id', (int) $request->getData('id'))->execute();
// @todo: can be edited? // @todo can be edited?
// @todo: adjust transfer protocolls // @todo adjust transfer protocolls
$new = $this->updateBillElementFromRequest($request, clone $old); $new = $this->updateBillElementFromRequest($request, clone $old);
@ -1311,7 +1313,7 @@ final class ApiBillController extends Controller
* *
* @return BillElement * @return BillElement
* *
* @todo: implement * @todo Implement API update function
* *
* @since 1.0.0 * @since 1.0.0
*/ */
@ -1327,7 +1329,7 @@ final class ApiBillController extends Controller
* *
* @return array<string, bool> * @return array<string, bool>
* *
* @todo: implement * @todo Implement API validation function
* *
* @since 1.0.0 * @since 1.0.0
*/ */
@ -1363,8 +1365,8 @@ final class ApiBillController extends Controller
return; return;
} }
// @todo: check if can be deleted // @todo check if can be deleted
// @todo: handle transactions and bill update // @todo handle transactions and bill update
/** @var \Modules\Billing\Models\BillElement $billElement */ /** @var \Modules\Billing\Models\BillElement $billElement */
$billElement = BillElementMapper::get()->where('id', (int) $request->getData('id'))->execute(); $billElement = BillElementMapper::get()->where('id', (int) $request->getData('id'))->execute();
@ -1406,8 +1408,17 @@ final class ApiBillController extends Controller
*/ */
public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{ {
// @todo: check permissions $accountId = $request->header->account;
$this->app->moduleManager->get('Editor', 'Api')->apiEditorDocUpdate($request, $response, $data); if (!$this->app->accountManager->get($accountId)->hasPermission(
PermissionType::MODIFY, $this->app->unitId, $this->app->appId, self::NAME, PermissionCategory::BILL_NOTE, $request->getDataInt('id'))
) {
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []);
$response->header->status = RequestStatusCode::R_403;
return;
}
$this->app->moduleManager->get('Editor', 'Api')->apiEditorUpdate($request, $response, $data);
} }
/** /**
@ -1425,7 +1436,16 @@ final class ApiBillController extends Controller
*/ */
public function apiNoteDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void public function apiNoteDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{ {
// @todo: check permissions $accountId = $request->header->account;
$this->app->moduleManager->get('Editor', 'Api')->apiEditorDocDelete($request, $response, $data); if (!$this->app->accountManager->get($accountId)->hasPermission(
PermissionType::DELETE, $this->app->unitId, $this->app->appId, self::NAME, PermissionCategory::BILL_NOTE, $request->getDataInt('id'))
) {
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []);
$response->header->status = RequestStatusCode::R_403;
return;
}
$this->app->moduleManager->get('Editor', 'Api')->apiEditorDelete($request, $response, $data);
} }
} }

View File

@ -219,7 +219,7 @@ final class ApiBillTypeController extends Controller
* *
* @return BillType * @return BillType
* *
* @todo: implement * @todo Implement API update function
* *
* @since 1.0.0 * @since 1.0.0
*/ */
@ -243,7 +243,7 @@ final class ApiBillTypeController extends Controller
* *
* @return array<string, bool> * @return array<string, bool>
* *
* @todo: implement * @todo Implement API validation function
* *
* @since 1.0.0 * @since 1.0.0
*/ */

View File

@ -132,10 +132,10 @@ final class ApiPriceController extends Controller
$queryMapper->where('type', $request->getData('price_type', 'int') ?? PriceType::SALES); $queryMapper->where('type', $request->getData('price_type', 'int') ?? PriceType::SALES);
$queryMapper->where('currency', \array_unique([$request->getData('price_currency', 'int'), null]), 'IN'); $queryMapper->where('currency', \array_unique([$request->getData('price_currency', 'int'), null]), 'IN');
// @todo: implement start and end // @todo implement start and end
/* /*
@todo: implement quantity @todo implement quantity
if ($request->hasData('price_quantity')) { if ($request->hasData('price_quantity')) {
$whereQuery = new Where(); $whereQuery = new Where();
$whereQuery->where('quantity', (int) $request->getData('price_quantity'), '<=') $whereQuery->where('quantity', (int) $request->getData('price_quantity'), '<=')
@ -148,7 +148,7 @@ final class ApiPriceController extends Controller
/** @var \Modules\Billing\Models\Price\Price[] $prices */ /** @var \Modules\Billing\Models\Price\Price[] $prices */
$prices = $queryMapper->execute(); $prices = $queryMapper->execute();
// Find base price (@todo: probably not a good solution) // Find base price (@todo probably not a good solution)
$bestBasePrice = null; $bestBasePrice = null;
foreach ($prices as $price) { foreach ($prices as $price) {
if ($price->price->value !== 0 && $price->priceNew === 0 if ($price->price->value !== 0 && $price->priceNew === 0
@ -169,7 +169,7 @@ final class ApiPriceController extends Controller
} }
} }
// @todo: implement prices which cannot be improved even if there are better prices available (i.e. some customer groups may not get better prices, Dentagen Beispiel) // @todo implement prices which cannot be improved even if there are better prices available (i.e. some customer groups may not get better prices, Dentagen Beispiel)
// alternatively set prices as 'improvable' => which whitelists a price as can be improved or 'alwaysimproces' which always overwrites other prices // alternatively set prices as 'improvable' => which whitelists a price as can be improved or 'alwaysimproces' which always overwrites other prices
// Find best price // Find best price
$bestPrice = null; $bestPrice = null;
@ -190,7 +190,7 @@ final class ApiPriceController extends Controller
$newPrice = (int) ((10000 / $price->discountPercentage) * $newPrice); $newPrice = (int) ((10000 / $price->discountPercentage) * $newPrice);
$newPrice = (int) (($price->quantity === 0 ? 10000 : $price->quantity) / (10000 + $price->bonus) * $newPrice); $newPrice = (int) (($price->quantity === 0 ? 10000 : $price->quantity) / (10000 + $price->bonus) * $newPrice);
// @todo: the calculation above regarding discount and bonus don't consider the purchased quantity. // @todo the calculation above regarding discount and bonus don't consider the purchased quantity.
// If a customer receives 1+1 but purchases 2, then he gets 2+2 (if multiply === true) which is better than 1+1 with multiply false. // If a customer receives 1+1 but purchases 2, then he gets 2+2 (if multiply === true) which is better than 1+1 with multiply false.
if ($newPrice < $bestPriceValue) { if ($newPrice < $bestPriceValue) {
@ -296,7 +296,7 @@ final class ApiPriceController extends Controller
* *
* @return array<string, bool> * @return array<string, bool>
* *
* @todo: consider to prevent name 'base'? * @todo consider to prevent name 'base'?
* Might not be possible because it is used internally as well (see apiItemCreate in ItemManagement) * Might not be possible because it is used internally as well (see apiItemCreate in ItemManagement)
* *
* @since 1.0.0 * @since 1.0.0
@ -395,8 +395,8 @@ final class ApiPriceController extends Controller
* *
* @return array<string, bool> * @return array<string, bool>
* *
* @todo: implement * @todo implement
* @todo: consider to block 'base' name * @todo consider to block 'base' name
* *
* @since 1.0.0 * @since 1.0.0
*/ */

View File

@ -14,7 +14,6 @@ declare(strict_types=1);
namespace Modules\Billing\Controller; namespace Modules\Billing\Controller;
use Modules\Admin\Models\Address;
use Modules\Attribute\Models\AttributeValue; use Modules\Attribute\Models\AttributeValue;
use Modules\Attribute\Models\NullAttributeValue; use Modules\Attribute\Models\NullAttributeValue;
use Modules\Billing\Models\Tax\TaxCombination; use Modules\Billing\Models\Tax\TaxCombination;
@ -30,6 +29,7 @@ use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\RequestAbstract; use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract; use phpOMS\Message\ResponseAbstract;
use phpOMS\Security\Guard; use phpOMS\Security\Guard;
use phpOMS\Stdlib\Base\Address;
/** /**
* Billing class. * Billing class.
@ -54,8 +54,8 @@ final class ApiTaxController extends Controller
*/ */
public function getTaxCodeFromClientItem(Client $client, Item $item, string $defaultCountry = '') : TaxCode public function getTaxCodeFromClientItem(Client $client, Item $item, string $defaultCountry = '') : TaxCode
{ {
// @todo: define default sales tax code if none available?! // @todo define default sales tax code if none available?!
// @todo: consider to actually use a ownsOne reference instead of only a string, this way the next line with the TaxCodeMapper can be removed // @todo consider to actually use a ownsOne reference instead of only a string, this way the next line with the TaxCodeMapper can be removed
/** @var \Modules\Billing\Models\Tax\TaxCombination $taxCombination */ /** @var \Modules\Billing\Models\Tax\TaxCombination $taxCombination */
$taxCombination = TaxCombinationMapper::get() $taxCombination = TaxCombinationMapper::get()
@ -195,7 +195,7 @@ final class ApiTaxController extends Controller
$taxCode = new NullAttributeValue(); $taxCode = new NullAttributeValue();
// @todo: need to consider own tax id as well // @todo need to consider own tax id as well
if ($taxOfficeAddress->getCountry() === $client->mainAddress->getCountry()) { if ($taxOfficeAddress->getCountry() === $client->mainAddress->getCountry()) {
$taxCode = $codes->getDefaultByValue($client->mainAddress->getCountry()); $taxCode = $codes->getDefaultByValue($client->mainAddress->getCountry());
} elseif (\in_array($taxOfficeAddress->getCountry(), ISO3166CharEnum::getRegion('eu')) } elseif (\in_array($taxOfficeAddress->getCountry(), ISO3166CharEnum::getRegion('eu'))
@ -413,7 +413,7 @@ final class ApiTaxController extends Controller
* *
* @return array<string, bool> * @return array<string, bool>
* *
* @todo: implement * @todo Implement API validation function
* *
* @since 1.0.0 * @since 1.0.0
*/ */

View File

@ -128,7 +128,7 @@ final class CliController extends Controller
/* Due */ /* Due */
$billDueTemp = $this->findBillDue($lines, $identifiers['bill_date'][$language]); $billDueTemp = $this->findBillDue($lines, $identifiers['bill_date'][$language]);
$billDue = $this->parseDate($billDueTemp, $supplier, $identifiers['date_format']); $billDue = $this->parseDate($billDueTemp, $supplier, $identifiers['date_format']);
// @todo: implement multiple due dates for bills // @todo implement multiple due dates for bills
/* Total Gross */ /* Total Gross */
$totalGross = $this->findBillGross($lines, $identifiers['total_gross'][$language]); $totalGross = $this->findBillGross($lines, $identifiers['total_gross'][$language]);
@ -248,7 +248,7 @@ final class CliController extends Controller
foreach ($lines as $row => $line) { foreach ($lines as $row => $line) {
if (\preg_match($match, $line, $found) === 1) { if (\preg_match($match, $line, $found) === 1) {
if ($row < $bestPos) { if ($row < $bestPos) {
// @todo: don't many invoices have the due date at the bottom? bestPos doesn't make sense?! // @todo don't many invoices have the due date at the bottom? bestPos doesn't make sense?!
$bestPos = $row; $bestPos = $row;
$bestMatch = \trim($found['bill_due']); $bestMatch = \trim($found['bill_due']);
} }
@ -355,7 +355,7 @@ final class CliController extends Controller
{ {
// bill_match_pattern // bill_match_pattern
foreach ($suppliers as $supplier) { foreach ($suppliers as $supplier) {
// @todo: consider to support regex? // @todo consider to support regex?
if ((!empty($supplier->getAttribute('bill_match_pattern')->value->valueStr) if ((!empty($supplier->getAttribute('bill_match_pattern')->value->valueStr)
&& \stripos($content, $supplier->getAttribute('bill_match_pattern')->value->valueStr) !== false) && \stripos($content, $supplier->getAttribute('bill_match_pattern')->value->valueStr) !== false)
) { ) {

View File

@ -1,6 +1,6 @@
# Individual Contributor License Agreement ("CLA") 1.0 # Individual Contributor License Agreement ("CLA") 1.0
Thank you for your interest in Karaka-Management (the "Company"). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Company must provide a Contributor License Agreement ("CLA") on file that has been made available to each Contributor. This license is for your protection as a Contributor as well as the protection of the Company and its users; it does not change your rights to use your own Contributions for any other purpose. Thank you for your interest in Jingga e. K. (the "Company"). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Company must provide a Contributor License Agreement ("CLA") on file that has been made available to each Contributor. This license is for your protection as a Contributor as well as the protection of the Company and its users; it does not change your rights to use your own Contributions for any other purpose.
By contributing to the Company You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Company. In return, the Company shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its bylaws in effect at the time of the Contribution. Except for the license granted herein to the Company and recipients of software distributed by the Company, You reserve all right, title, and interest in and to Your Contributions. By contributing to the Company You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Company. In return, the Company shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its bylaws in effect at the time of the Contribution. Except for the license granted herein to the Company and recipients of software distributed by the Company, You reserve all right, title, and interest in and to Your Contributions.

View File

@ -684,7 +684,7 @@ class Bill implements \JsonSerializable
$this->grossSales->add($element->totalSalesPriceGross->getInt()); $this->grossSales->add($element->totalSalesPriceGross->getInt());
$this->netDiscount->add($element->totalDiscountP->getInt()); $this->netDiscount->add($element->totalDiscountP->getInt());
// @todo: Discount might be in quantities // @todo Discount might be in quantities
$this->grossDiscount->add((int) ($element->taxR->getInt() * $element->totalDiscountP->getInt() / 10000)); $this->grossDiscount->add((int) ($element->taxR->getInt() * $element->totalDiscountP->getInt() / 10000));
} }

View File

@ -39,7 +39,7 @@ class BillElement implements \JsonSerializable
public int $order = 0; public int $order = 0;
/** @todo: consider to reference the model instead of the int, this would make it much easier in other places like the shop */ /** @todo consider to reference the model instead of the int, this would make it much easier in other places like the shop */
public ?int $item = null; public ?int $item = null;
public string $itemNumber = ''; public string $itemNumber = '';
@ -196,7 +196,7 @@ class BillElement implements \JsonSerializable
} }
$this->quantity = $quantity; $this->quantity = $quantity;
// @todo: recalculate all the prices!!! // @todo recalculate all the prices!!!
} }
/** /**
@ -247,8 +247,8 @@ class BillElement implements \JsonSerializable
$element->itemDescription = $item->getL11n('description_short')->content; $element->itemDescription = $item->getL11n('description_short')->content;
$element->quantity = $quantity; $element->quantity = $quantity;
// @todo: Use pricing instead of the default sales price // @todo Use pricing instead of the default sales price
// @todo: discounts might be in quantities // @todo discounts might be in quantities
$element->singleListPriceNet->setInt($item->salesPrice->getInt()); $element->singleListPriceNet->setInt($item->salesPrice->getInt());
$element->totalListPriceNet->setInt($element->quantity * $item->salesPrice->getInt()); $element->totalListPriceNet->setInt($element->quantity * $item->salesPrice->getInt());
$element->singleSalesPriceNet->setInt($item->salesPrice->getInt()); $element->singleSalesPriceNet->setInt($item->salesPrice->getInt());
@ -280,8 +280,8 @@ class BillElement implements \JsonSerializable
$element->subscription = new Subscription(); $element->subscription = new Subscription();
$element->subscription->bill = $element->bill->id; $element->subscription->bill = $element->bill->id;
$element->subscription->item = $element->item; $element->subscription->item = $element->item;
$element->subscription->start = new \DateTime('now'); // @todo: change to bill performanceDate $element->subscription->start = new \DateTime('now'); // @todo change to bill performanceDate
$element->subscription->end = new SmartDateTime('now'); // @todo: depends on subscription type $element->subscription->end = new SmartDateTime('now'); // @todo depends on subscription type
$element->subscription->end->smartModify(m: 1); $element->subscription->end->smartModify(m: 1);
$element->subscription->quantity = $element->quantity; $element->subscription->quantity = $element->quantity;

View File

@ -35,4 +35,6 @@ abstract class PermissionCategory extends Enum
public const PRIVATE_DASHBOARD = 5; public const PRIVATE_DASHBOARD = 5;
public const PRIVATE_BILL_UPLOAD = 6; public const PRIVATE_BILL_UPLOAD = 6;
public const BILL_NOTE = 7;
} }

View File

@ -182,7 +182,7 @@ final class PriceMapper extends DataMapperFactory
AND (unit = ? OR unit = null) AND (unit = ? OR unit = null)
*/ */
// @todo: allow nested where clause (already possible with the query builder, but not with the mappers) // @todo allow nested where clause (already possible with the query builder, but not with the mappers)
return []; return [];
} }

View File

@ -141,7 +141,7 @@ final class PurchaseBillMapper extends BillMapper
*/ */
public static function getLastOrderDateByItemId(int $id) : ?\DateTimeImmutable public static function getLastOrderDateByItemId(int $id) : ?\DateTimeImmutable
{ {
// @todo: only delivers/invoice/production (no offers ...) // @todo only delivers/invoice/production (no offers ...)
$query = new Builder(self::$db); $query = new Builder(self::$db);
/** @var false|array $result */ /** @var false|array $result */
@ -163,7 +163,7 @@ final class PurchaseBillMapper extends BillMapper
*/ */
public static function getLastOrderDateBySupplierId(int $id) : ?\DateTimeImmutable public static function getLastOrderDateBySupplierId(int $id) : ?\DateTimeImmutable
{ {
// @todo: only delivers/invoice/production (no offers ...) // @todo only delivers/invoice/production (no offers ...)
$query = new Builder(self::$db); $query = new Builder(self::$db);
/** @var false|array $result */ /** @var false|array $result */

View File

@ -141,7 +141,7 @@ final class SalesBillMapper extends BillMapper
*/ */
public static function getLastOrderDateByItemId(int $id) : ?\DateTimeImmutable public static function getLastOrderDateByItemId(int $id) : ?\DateTimeImmutable
{ {
// @todo: only delivers/invoice/production (no offers ...) // @todo only delivers/invoice/production (no offers ...)
$query = new Builder(self::$db); $query = new Builder(self::$db);
/** @var false|array $result */ /** @var false|array $result */
@ -163,7 +163,7 @@ final class SalesBillMapper extends BillMapper
*/ */
public static function getLastOrderDateByClientId(int $id) : ?\DateTimeImmutable public static function getLastOrderDateByClientId(int $id) : ?\DateTimeImmutable
{ {
// @todo: only delivers/invoice/production (no offers ...) // @todo only delivers/invoice/production (no offers ...)
$query = new Builder(self::$db); $query = new Builder(self::$db);
/** @var false|array $result */ /** @var false|array $result */

View File

@ -43,7 +43,7 @@ class TaxCombination implements \JsonSerializable
public string $taxCode = ''; public string $taxCode = '';
// @todo: consider to add the tax code object directly, it is annoying to make a manuall mapper call which is often required afterwards. // @todo consider to add the tax code object directly, it is annoying to make a manuall mapper call which is often required afterwards.
public int $taxType = BillTaxType::SALES; public int $taxType = BillTaxType::SALES;