Quick backup before crash

This commit is contained in:
Dennis Eichhorn 2023-06-13 18:55:51 +00:00
parent bbb42b61e2
commit da8b60b506
9 changed files with 80 additions and 27 deletions

View File

@ -136,11 +136,11 @@ $pdf->setXY($rightPos + 26 + 2, $tempY, true);
$pdf->MultiCell(
25, 30,
$bill->number . "\n"
. $bill->billDate->format('Y-m-d') . "\n"
. $bill->performanceDate->format('Y-m-d') . "\n"
. ($bill->billDate?->format('Y-m-d') ?? '0') . "\n"
. ($bill->performanceDate?->format('Y-m-d') ?? '0') . "\n"
. $bill->accountNumber . "\n"
. '' . "\n" /* @todo: implement customer / supplier reference as string */
. $bill->billDate->format('Y-m-d'), /* Consider to add dueDate in addition */
. ($bill->billDate?->format('Y-m-d') ?? '0'), /* Consider to add dueDate in addition */
0, 'L'
);
$pdf->Ln();
@ -308,6 +308,6 @@ $pdf->Ln();
//Close and output PDF document
$pdf->Output(
$this->data['path'] ?? ($bill->billDate->format('Y-m-d') . '_' . $bill->number . '.pdf'),
$this->data['path'] ?? (($bill->billDate?->format('Y-m-d') ?? '0') . '_' . $bill->number . '.pdf'),
'I'
);

View File

@ -104,16 +104,16 @@ final class Installer extends InstallerAbstract
/**
* Install default attribute types
*
* @param ApplicationAbstract $app Application
* @param array<array{name:string, l11n?:array<string, string>, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array<string, mixed>}> $attributes Attribute definition
* @param ApplicationAbstract $app Application
* @param array $attributes Attribute definition
*
* @return array<string, array>
* @return array
*
* @since 1.0.0
*/
private static function createBillAttributeTypes(ApplicationAbstract $app, array $attributes) : array
{
/** @var array<string, array> $billAttrType */
/** @var array $billAttrType */
$billAttrType = [];
/** @var \Modules\Billing\Controller\ApiController $module */
@ -258,7 +258,7 @@ final class Installer extends InstallerAbstract
/** @var \Modules\Billing\Controller\ApiController $module */
$module = $app->moduleManager->getModuleInstance('Billing');
/** @var \Modules\Attribute\Models\ItemAttributeTypeMapper $itemAttributeSales */
/** @var \Modules\Attribute\Models\AttributeType $itemAttributeSales */
$itemAttributeSales = ItemAttributeTypeMapper::get()
->with('defaults')
->where('name', 'sales_tax_code')

View File

@ -24,6 +24,7 @@ use Modules\Billing\Models\BillElementMapper;
use Modules\Billing\Models\BillMapper;
use Modules\Billing\Models\BillStatus;
use Modules\Billing\Models\BillTypeMapper;
use Modules\Billing\Models\NullBillElement;
use Modules\Billing\Models\SettingsEnum;
use Modules\ClientManagement\Models\Client;
use Modules\ClientManagement\Models\ClientMapper;
@ -187,7 +188,7 @@ final class ApiBillController extends Controller
/**
* Create a base Bill object with default values
*
* @param Client $client The client object for whom the bill is being created
* @param Client|Supplier $account The client or supplier object for whom the bill is being created
* @param RequestAbstract $request The request object that contains the header account
*
* @return Bill The new Bill object with default values
@ -251,7 +252,9 @@ final class ApiBillController extends Controller
$validLanguages = [];
if (!empty($settings) && !empty($settings->content)) {
$validLanguages = \json_decode($settings->content, true);
} else {
}
if (empty($validLanguages) || !\is_array($validLanguages)) {
$validLanguages = [
ISO639x1Enum::_EN,
];
@ -441,6 +444,7 @@ final class ApiBillController extends Controller
}
if ($collection === null) {
/** @var \Modules\Media\Models\Collection $collection */
$collection = MediaMapper::getParentCollection($path)
->limit(1)
->execute();
@ -591,6 +595,10 @@ final class ApiBillController extends Controller
->where('l11n/language', $bill->language)
->execute();
if ($bill->client === null) {
return new NullBillElement();
}
$element = $this->createBaseBillElement($bill->client, $item, $bill, $request);
$element->bill = $bill->id;
@ -621,6 +629,19 @@ final class ApiBillController extends Controller
return [];
}
/**
* Render bill media
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiMediaRender(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void
{
// @todo: check if has permission
@ -727,7 +748,7 @@ final class ApiBillController extends Controller
$pdfDir = __DIR__ . '/../../../Modules/Media/Files' . $path;
$view->data['bill'] = $bill;
$view->data['path'] = $pdfDir . '/' .$bill->billDate->format('Y-m-d') . '_' . $bill->number . '.pdf';
$view->data['path'] = $pdfDir . '/' . ($bill->billDate?->format('Y-m-d') ?? '0') . '_' . $bill->number . '.pdf';
$view->data['bill_creator'] = $request->getDataString('bill_creator');
$view->data['bill_title'] = $request->getDataString('bill_title');
@ -878,7 +899,7 @@ final class ApiBillController extends Controller
// @codeCoverageIgnoreEnd
}
$billFileName = $bill->billDate->format('Y-m-d') . '_' . $bill->number . '.pdf';
$billFileName = ($bill->billDate?->format('Y-m-d') ?? '0') . '_' . $bill->number . '.pdf';
\file_put_contents($pdfDir . '/' . $billFileName, $pdf);
if (!\is_file($pdfDir . '/' . $billFileName)) {
@ -911,7 +932,7 @@ final class ApiBillController extends Controller
->with('attributes')
->with('attributes/type')
->with('attributes/value')
->where('id', $bill->client->id)
->where('id', $bill->client?->id ?? 0)
->where('attributes/type/name', ['bill_emails', 'bill_email_address'], 'IN')
->execute();
@ -924,6 +945,7 @@ final class ApiBillController extends Controller
}
// Add type to media
/** @var \Model\Setting $originalType */
$originalType = $this->app->appSettings->get(
names: SettingsEnum::ORIGINAL_MEDIA_TYPE,
module: self::NAME
@ -953,28 +975,41 @@ final class ApiBillController extends Controller
$this->createStandardCreateResponse($request, $response, $media);
}
/**
* Send bill as email
*
* @param Media $media Media to send
* @param string $email Email address
* @param string $language Message language
*
* @return void
*
* @since 1.0.0
*/
public function sendBillEmail(Media $media, string $email, string $language = 'en') : void
{
$handler = $this->app->moduleMaanger->get('Admin', 'Api')->setUpServerMailHandler();
$handler = $this->app->moduleManager->get('Admin', 'Api')->setUpServerMailHandler();
$emailSettings = $this->app->appSettings->get(
/** @var \Model\Setting $emailFrom */
$emailFrom = $this->app->appSettings->get(
names: AdminSettingsEnum::MAIL_SERVER_ADDR,
module: 'Admin'
);
$emailSettings = $this->app->appSettings->get(
/** @var \Model\Setting $billingTemplate */
$billingTemplate = $this->app->appSettings->get(
names: SettingsEnum::BILLING_CUSTOMER_EMAIL_TEMPLATE,
module: 'Billing'
);
$mail = EmailMapper::get()
->with('l11n')
->where('id', (int) $emailSettings->content)
->where('id', (int) $billingTemplate->content)
->where('l11n/language', $language)
->execute();
$mail = new Email();
$mail->setFrom($emailSettings->content);
$mail->setFrom($emailFrom->content);
$mail->addTo($email);
$mail->addAttachment($media->getAbsolutePath(), $media->name);
@ -1015,6 +1050,7 @@ final class ApiBillController extends Controller
return;
}
/** @var \Modules\Editor\Models\EditorDoc $model */
$model = $response->get($request->uri->__toString())['response'];
$this->createModelRelation($request->header->account, $request->getDataInt('id'), $model->id, BillMapper::class, 'bill_note', '', $request->getOrigin());
}

View File

@ -96,6 +96,7 @@ final class ApiPurchaseController extends Controller
$mediaRequest->setData('parse_content', true, true);
$this->app->moduleManager->get('Billing', 'Api')->apiMediaAddToBill($mediaRequest, $mediaResponse, $data);
/** @var \Modules\Media\Models\Media[] $uploaded */
$uploaded = $mediaResponse->get('')['response']['upload'];
$in = \reset($uploaded)->getAbsolutePath(); // pdf is parsed in $in->content

View File

@ -120,7 +120,7 @@ final class BackendController extends Controller
$view->data['bill'] = $bill;
/** @var \Modules\Auditor\Models\Auditor[] $logsBill */
/** @var \Modules\Auditor\Models\Audit[] $logsBill */
$logsBill = AuditMapper::getAll()
->with('createdBy')
->where('module', 'Billing')
@ -128,7 +128,7 @@ final class BackendController extends Controller
->where('ref', $bill->id)
->execute();
/** @var \Modules\Auditor\Models\Auditor[] $logsElements */
/** @var \Modules\Auditor\Models\Audit[] $logsElements */
$logsElements = AuditMapper::getAll()
->with('createdBy')
->where('module', 'Billing')

View File

@ -407,7 +407,7 @@ final class CliController extends Controller
return \DateTime::createFromFormat(
$supplier->getAttribute('bill_date_format')->value->valueStr ?? '',
$date
);
) ?? new \DateTime('1970-01-01');
}
foreach ($formats as $format) {

View File

@ -17,6 +17,7 @@ namespace Modules\Billing\Models;
use Modules\Finance\Models\TaxCode;
use Modules\ItemManagement\Models\Item;
use phpOMS\Stdlib\Base\FloatInt;
use phpOMS\Stdlib\Base\SmartDateTime;
/**
* Bill class.
@ -272,12 +273,15 @@ class BillElement implements \JsonSerializable
if (!empty($element->bill)
&& $item->getAttribute('subscription')->value->getValue() === 1
&& $element->item !== null
) {
$element->subscription = new Subscription();
$element->subscription->bill = $element->bill;
$element->subscription->item = $element->item;
$element->subscription->start = $element->quantity;
$element->subscription->end = $element->quantity;
$element->subscription = new Subscription();
$element->subscription->bill = $element->bill;
$element->subscription->item = $element->item;
$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->smartModify(m: 1);
$element->subscription->quantity = $element->quantity;
$element->subscription->autoRenew = $item->getAttribute('subscription_renewal_type')->value->getValue() === 1;
}

View File

@ -95,6 +95,11 @@ class Price implements \JsonSerializable
public ?\DateTime $end = null;
/**
* Constructor.
*
* @since 1.0.0
*/
public function __construct()
{
$this->item = new NullItem();

View File

@ -155,6 +155,13 @@ final class PriceMapper extends DataMapperFactory
*/
public const PRIMARYFIELD = 'billing_price_id';
/**
* Find price for a client
*
* @return Price[]
*
* @since 1.0.0
*/
public static function findClientPrice() : array
{
/*