diff --git a/app/Abstracts/View/Components/Transaction.php b/app/Abstracts/View/Components/Transaction.php
new file mode 100644
index 000000000..4174533cc
--- /dev/null
+++ b/app/Abstracts/View/Components/Transaction.php
@@ -0,0 +1,175 @@
+ $alias . 'general.' . $default_key,
+ 'prefix' => $alias . $prefix . '.' . $default_key,
+ 'config_general' => $alias . 'general.' . $config_key,
+ 'config_prefix' => $alias . $prefix . '.' . $config_key,
+ ];
+
+ switch ($trans_type) {
+ case 'trans':
+ foreach ($translations as $trans) {
+ if (trans($trans) !== $trans) {
+ return $trans;
+ }
+ }
+
+ break;
+ case 'trans_choice':
+ foreach ($translations as $trans_choice) {
+ if (trans_choice($trans_choice, 1) !== $trans_choice) {
+ return $trans_choice;
+ }
+ }
+
+ break;
+ }
+
+ return $translation;
+ }
+
+ public function getRouteFromConfig($type, $config_key, $config_parameters = [])
+ {
+ $route = '';
+
+ // if set config trasnlation config_key
+ if ($route = config('type.' . $type . '.route.' . $config_key)) {
+ return $route;
+ }
+
+ $alias = config('type.' . $type . '.alias');
+ $prefix = config('type.' . $type . '.route.prefix');
+
+ // if use module set module alias
+ if (!empty($alias)) {
+ $route .= $alias . '.';
+ }
+
+ if (!empty($prefix)) {
+ $route .= $prefix . '.';
+ }
+
+ $route .= $config_key;
+
+ try {
+ route($route, $config_parameters);
+ } catch (\Exception $e) {
+ try {
+ $route = Str::plural($type, 2) . '.' . $config_key;
+
+ route($route, $config_parameters);
+ } catch (\Exception $e) {
+ $route = '';
+ }
+ }
+
+ return $route;
+ }
+
+ public function getPermissionFromConfig($type, $config_key)
+ {
+ $permission = '';
+
+ // if set config trasnlation config_key
+ if ($permission = config('type.' . $type . '.permission.' . $config_key)) {
+ return $permission;
+ }
+
+ $alias = config('type.' . $type . '.alias');
+ $group = config('type.' . $type . '.group');
+ $prefix = config('type.' . $type . '.permission.prefix');
+
+ $permission = $config_key . '-';
+
+ // if use module set module alias
+ if (!empty($alias)) {
+ $permission .= $alias . '-';
+ }
+
+ // if controller in folder it must
+ if (!empty($group)) {
+ $permission .= $group . '-';
+ }
+
+ $permission .= $prefix;
+
+ return $permission;
+ }
+
+ public function getHideFromConfig($type, $config_key)
+ {
+ $hide = false;
+
+ $hides = config('type.' . $type . '.hide');
+
+ if (!empty($hides) && (in_array($config_key, $hides))) {
+ $hide = true;
+ }
+
+ return $hide;
+ }
+
+ public function getClassFromConfig($type, $config_key)
+ {
+ $class_key = 'type.' . $type . '.class.' . $config_key;
+
+ return config($class_key, '');
+ }
+
+ public function getCategoryFromConfig($type)
+ {
+ $category_type = '';
+
+ // if set config trasnlation config_key
+ if ($category_type = config('type.' . $type . '.category_type')) {
+ return $category_type;
+ }
+
+ switch ($type) {
+ case 'bill':
+ case 'expense':
+ case 'purchase':
+ $category_type = 'expense';
+ break;
+ case 'item':
+ $category_type = 'item';
+ break;
+ case 'other':
+ $category_type = 'other';
+ break;
+ case 'transfer':
+ $category_type = 'transfer';
+ break;
+ default:
+ $category_type = 'income';
+ break;
+ }
+
+ return $category_type;
+ }
+}
diff --git a/app/Abstracts/View/Components/TransactionShow.php b/app/Abstracts/View/Components/TransactionShow.php
new file mode 100644
index 000000000..ff719f2dd
--- /dev/null
+++ b/app/Abstracts/View/Components/TransactionShow.php
@@ -0,0 +1,899 @@
+type = $type;
+ $this->transaction = $transaction;
+ $this->transactionTemplate = $this->getTransactionTemplate($type, $transactionTemplate);
+ $this->logo = $this->getLogo($logo);
+ $this->signedUrl = $this->getSignedUrl($type, $signedUrl);
+
+ $this->histories = $this->getHistories($histories);
+
+ $this->date_format = $this->getCompanyDateFormat();
+
+ $this->textHistories = $this->getTextHistories($type, $textHistories);
+
+ $this->checkButtonReconciled = $checkButtonReconciled;
+
+ $this->payment_methods = ($payment_methods) ?: Modules::getPaymentMethods();
+
+ $this->routeButtonAddNew = $this->getRouteButtonAddNew($type, $routeButtonAddNew);
+ $this->routeButtonEdit = $this->getRouteButtonEdit($type, $routeButtonEdit);
+ $this->routeButtonDuplicate = $this->getRouteButtonDuplicate($type, $routeButtonDuplicate);
+ $this->routeButtonPrint = $this->getRouteButtonPrint($type, $routeButtonPrint);
+ $this->routeButtonPdf = $this->getRouteButtonPdf($type, $routeButtonPdf);
+ $this->routeButtonDelete = $this->getRouteButtonDelete($type, $routeButtonDelete);
+
+ $this->permissionCreate = $this->getPermissionCreate($type, $permissionCreate);
+ $this->permissionUpdate = $this->getPermissionUpdate($type, $permissionUpdate);
+ $this->permissionDelete = $this->getPermissionDelete($type, $permissionDelete);
+
+ $this->hideButtonGroupDivider1 = $hideButtonGroupDivider1;
+ $this->hideButtonGroupDivider2 = $hideButtonGroupDivider2;
+ $this->hideButtonGroupDivider3 = $hideButtonGroupDivider3;
+
+ $this->hideButtonMoreActions = $hideButtonMoreActions;
+ $this->hideButtonAddNew = $hideButtonAddNew;
+ $this->hideButtonEdit = $hideButtonEdit;
+ $this->hideButtonDuplicate = $hideButtonDuplicate;
+ $this->hideButtonPrint = $hideButtonPrint;
+ $this->hideButtonPdf = $hideButtonPdf;
+ $this->hideButtonDelete = $hideButtonDelete;
+
+ $this->hideHeader = $hideHeader;
+ $this->hideFooter = $hideFooter;
+ $this->hideFooterHistories = $hideFooterHistories;
+
+ $this->classHeaderAccount = $this->getclassHeaderAccount($type, $classHeaderAccount);
+ $this->classHeaderContact = $this->getClassHeaderContact($type, $classHeaderContact);
+ $this->classHeaderCategory = $this->getClassHeaderCategory($type, $classHeaderCategory);
+ $this->classHeaderAmount = $this->getClassHeaderAmount($type, $classHeaderAmount);
+ $this->classHeaderPaidAt = $this->getclassHeaderPaidAt($type, $classHeaderPaidAt);
+
+ $this->classFooterHistories = $this->getClassFooterHistories($type, $classFooterHistories);
+
+ $this->hideHeaderAccount = $hideHeaderAccount;
+ $this->hideHeaderCategory = $hideHeaderCategory;
+ $this->hideHeaderContact = $hideHeaderContact;
+ $this->hideHeaderCategory = $hideHeaderCategory;
+ $this->hideHeaderAmount = $hideHeaderAmount;
+ $this->hideHeaderPaidAt = $hideHeaderPaidAt;
+
+ $this->textHeaderAccount = $this->getTextHeaderAccount($type, $textHeaderAccount);
+ $this->textHeaderCategory = $this->getTextHeaderCategory($type, $textHeaderCategory);
+ $this->textHeaderContact = $this->getTextHeaderContact($type, $textHeaderContact);
+ $this->textHeaderAmount = $this->getTextHeaderAmount($type, $textHeaderAmount);
+ $this->textHeaderPaidAt = $this->gettextHeaderPaidAt($type, $textHeaderPaidAt);
+
+ $this->hideTimelineCreate = $hideTimelineCreate;
+ $this->hideButtonEmail = $hideButtonEmail;
+ $this->hideButtonShare = $hideButtonShare;
+
+ $this->routeButtonEmail = $this->getRouteButtonEmail($type, $routeButtonEmail);
+
+ $this->hideCompanyDetails = $hideCompanyDetails;
+ $this->hideCompanyLogo = $hideCompanyLogo;
+ $this->hideCompanyName = $hideCompanyName;
+ $this->hideContactAddress = $hideContactAddress;
+ $this->hideContactTaxNumber = $hideContactTaxNumber;
+ $this->hideContactPhone = $hideContactPhone;
+ $this->hideContactEmail = $hideContactEmail;
+ $this->hideIssuedAt = $hideIssuedAt;
+ $this->hideDueAt = $hideDueAt;
+
+ $this->textContactInfo = $textContactInfo;
+ $this->textIssuedAt = $textIssuedAt;
+ $this->textDueAt = $textDueAt;
+
+ $this->hideName = $this->getHideName($type, $hideName);
+ $this->hideDescription = $this->getHideDescription($type, $hideDescription);
+ $this->hideAmount = $this->getHideAmount($type, $hideAmount);
+ $this->hideAttachment = $hideAttachment;
+
+ $this->attachment = '';
+
+ if (!empty($attachment)) {
+ $this->attachment = $attachment;
+ } else if (!empty($transaction)) {
+ $this->attachment = $transaction->attachment;
+ }
+
+ $this->textAmount = $textAmount;
+
+ $this->textDeleteModal = $textDeleteModal;
+ }
+
+ protected function getTransactionTemplate($type, $transactionTemplate)
+ {
+ if (!empty($transactionTemplate)) {
+ return $transactionTemplate;
+ }
+
+ if ($template = config('type.' . $type . 'template', false)) {
+ return $template;
+ }
+
+ if (!empty($alias = config('type.' . $type . '.alias'))) {
+ $type = $alias . '.' . str_replace('-', '_', $type);
+ }
+
+ $transactionTemplate = setting($this->getSettingKey($type, 'template')) ?: 'default';
+
+ return $transactionTemplate;
+ }
+
+ protected function getLogo($logo)
+ {
+ if (!empty($logo)) {
+ return $logo;
+ }
+
+ $media = Media::find(setting('company.logo'));
+
+ if (!empty($media)) {
+ $path = $media->getDiskPath();
+
+ if (Storage::missing($path)) {
+ return $logo;
+ }
+ } else {
+ $path = base_path('public/img/company.png');
+ }
+
+ try {
+ $image = Image::cache(function($image) use ($media, $path) {
+ $width = setting('invoice.logo_size_width');
+ $height = setting('invoice.logo_size_height');
+
+ if ($media) {
+ $image->make(Storage::get($path))->resize($width, $height)->encode();
+ } else {
+ $image->make($path)->resize($width, $height)->encode();
+ }
+ });
+ } catch (NotReadableException | \Exception $e) {
+ Log::info('Company ID: ' . company_id() . ' components/transactionshow.php exception.');
+ Log::info($e->getMessage());
+
+ $path = base_path('public/img/company.png');
+
+ $image = Image::cache(function($image) use ($path) {
+ $width = setting('invoice.logo_size_width');
+ $height = setting('invoice.logo_size_height');
+
+ $image->make($path)->resize($width, $height)->encode();
+ });
+ }
+
+ if (empty($image)) {
+ return $logo;
+ }
+
+ $extension = File::extension($path);
+
+ return 'data:image/' . $extension . ';base64,' . base64_encode($image);
+ }
+
+ protected function getHistories($histories)
+ {
+ if (!empty($histories)) {
+ return $histories;
+ }
+
+ $histories[] = $this->transaction;
+
+ return $histories;
+ }
+
+ protected function getSignedUrl($type, $signedUrl)
+ {
+ if (!empty($signedUrl)) {
+ return $signedUrl;
+ }
+
+ $page = config('type.' . $type . '.route.prefix');
+ $alias = config('type.' . $type . '.alias');
+
+ $route = '';
+
+ if (!empty($alias)) {
+ $route .= $alias . '.';
+ }
+
+ $route .= 'signed.' . $page . '.show';
+
+ try {
+ route($route, [$this->transaction->id, 'company_id' => company_id()]);
+
+ $signedUrl = URL::signedRoute($route, [$this->transaction->id]);
+ } catch (\Exception $e) {
+ $signedUrl = URL::signedRoute('signed.payments.show', [$this->transaction->id]);
+ }
+
+ return $signedUrl;
+ }
+
+ protected function getTextHistories($type, $textHistories)
+ {
+ if (!empty($textHistories)) {
+ return $textHistories;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'histories', 'histories');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'invoices.histories';
+ }
+
+ protected function getRouteButtonAddNew($type, $routeButtonAddNew)
+ {
+ if (!empty($routeButtonAddNew)) {
+ return $routeButtonAddNew;
+ }
+
+ $route = $this->getRouteFromConfig($type, 'create');
+
+ if (!empty($route)) {
+ return $route;
+ }
+
+ return 'revenues.create';
+ }
+
+ protected function getRouteButtonEdit($type, $routeButtonEdit)
+ {
+ if (!empty($routeButtonEdit)) {
+ return $routeButtonEdit;
+ }
+
+ //example route parameter.
+ $parameter = 1;
+
+ $route = $this->getRouteFromConfig($type, 'edit', $parameter);
+
+ if (!empty($route)) {
+ return $route;
+ }
+
+ return 'revenues.edit';
+ }
+
+ protected function getRouteButtonDuplicate($type, $routeButtonDuplicate)
+ {
+ if (!empty($routeButtonDuplicate)) {
+ return $routeButtonDuplicate;
+ }
+
+ //example route parameter.
+ $parameter = 1;
+
+ $route = $this->getRouteFromConfig($type, 'duplicate', $parameter);
+
+ if (!empty($route)) {
+ return $route;
+ }
+
+ return 'revenues.duplicate';
+ }
+
+ protected function getRouteButtonPrint($type, $routeButtonPrint)
+ {
+ if (!empty($routeButtonPrint)) {
+ return $routeButtonPrint;
+ }
+
+ //example route parameter.
+ $parameter = 1;
+
+ $route = $this->getRouteFromConfig($type, 'print', $parameter);
+
+ if (!empty($route)) {
+ return $route;
+ }
+
+ return 'revenues.print';
+ }
+
+ protected function getRouteButtonPdf($type, $routeButtonPdf)
+ {
+ if (!empty($routeButtonPdf)) {
+ return $routeButtonPdf;
+ }
+
+ //example route parameter.
+ $parameter = 1;
+
+ $route = $this->getRouteFromConfig($type, 'pdf', $parameter);
+
+ if (!empty($route)) {
+ return $route;
+ }
+
+ return 'revenues.pdf';
+ }
+
+ protected function getRouteButtonDelete($type, $routeButtonDelete)
+ {
+ if (!empty($routeButtonDelete)) {
+ return $routeButtonDelete;
+ }
+
+ //example route parameter.
+ $parameter = 1;
+
+ $route = $this->getRouteFromConfig($type, 'destroy', $parameter);
+
+ if (!empty($route)) {
+ return $route;
+ }
+
+ return 'revenues.destroy';
+ }
+
+ protected function getRouteButtonEmail($type, $routeButtonEmail)
+ {
+ if (!empty($routeButtonEmail)) {
+ return $routeButtonEmail;
+ }
+
+ //example route parameter.
+ $parameter = 1;
+
+ $route = $this->getRouteFromConfig($type, 'email', $parameter);
+
+ if (!empty($route)) {
+ return $route;
+ }
+
+ return 'revenues.email';
+ }
+
+ protected function getPermissionCreate($type, $permissionCreate)
+ {
+ if (!empty($permissionCreate)) {
+ return $permissionCreate;
+ }
+
+ $permissionCreate = $this->getPermissionFromConfig($type, 'create');
+
+ return $permissionCreate;
+ }
+
+ protected function getPermissionUpdate($type, $permissionUpdate)
+ {
+ if (!empty($permissionUpdate)) {
+ return $permissionUpdate;
+ }
+
+ $permissionUpdate = $this->getPermissionFromConfig($type, 'update');
+
+ return $permissionUpdate;
+ }
+
+ protected function getPermissionDelete($type, $permissionDelete)
+ {
+ if (!empty($permissionDelete)) {
+ return $permissionDelete;
+ }
+
+ $permissionDelete = $this->getPermissionFromConfig($type, 'delete');
+
+ return $permissionDelete;
+ }
+
+ protected function getTextHeaderAccount($type, $textHeaderAccount)
+ {
+ if (!empty($textHeaderAccount)) {
+ return $textHeaderAccount;
+ }
+
+ $default_key = Str::plural(config('type.' . $type . '.contact_type'), 2);
+
+ $translation = $this->getTextFromConfig($type, 'header_contact', $default_key, 'trans_choice');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.customers';
+ }
+
+ protected function getTextHeaderCategory($type, $textHeaderCategory)
+ {
+ if (!empty($textHeaderCategory)) {
+ return $textHeaderCategory;
+ }
+
+ $default_key = Str::plural(config('type.' . $type . '.contact_type'), 2);
+
+ $translation = $this->getTextFromConfig($type, 'header_contact', $default_key, 'trans_choice');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.customers';
+ }
+
+ protected function getTextHeaderContact($type, $textHeaderContact)
+ {
+ if (!empty($textHeaderContact)) {
+ return $textHeaderContact;
+ }
+
+ $default_key = Str::plural(config('type.' . $type . '.contact_type'), 2);
+
+ $translation = $this->getTextFromConfig($type, 'header_contact', $default_key, 'trans_choice');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.customers';
+ }
+
+ protected function getTextHeaderAmount($type, $textHeaderAmount)
+ {
+ if (!empty($textHeaderAmount)) {
+ return $textHeaderAmount;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'header_amount', 'amount_due');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.amount_due';
+ }
+
+ protected function gettextHeaderPaidAt($type, $textHeaderPaidAt)
+ {
+ if (!empty($textHeaderPaidAt)) {
+ return $textHeaderPaidAt;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'header_due_at', 'due_on');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.due_on';
+ }
+
+ protected function getclassHeaderAccount($type, $classHeaderAccount)
+ {
+ if (!empty($classHeaderAccount)) {
+ return $classHeaderAccount;
+ }
+
+ $class = $this->getClassFromConfig($type, 'header_status');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-md-2';
+ }
+
+ protected function getClassHeaderContact($type, $classHeaderContact)
+ {
+ if (!empty($classHeaderContact)) {
+ return $classHeaderContact;
+ }
+
+ $class = $this->getClassFromConfig($type, 'header_contact');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-md-3';
+ }
+
+ protected function getClassHeaderCategory($type, $classHeaderCategory)
+ {
+ if (!empty($classHeaderCategory)) {
+ return $classHeaderCategory;
+ }
+
+ $class = $this->getClassFromConfig($type, 'header_contact');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-md-3';
+ }
+
+ protected function getClassHeaderAmount($type, $classHeaderAmount)
+ {
+ if (!empty($classHeaderAmount)) {
+ return $classHeaderAmount;
+ }
+
+ $class = $this->getClassFromConfig($type, 'header_amount');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-md-2';
+ }
+
+ protected function getclassHeaderAccountAt($type, $classHeaderAccountAt)
+ {
+ if (!empty($classHeaderPaidAt)) {
+ return $classHeaderPaidAt;
+ }
+
+ $class = $this->getClassFromConfig($type, 'header_paid_at');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-md-2';
+ }
+
+ protected function getclassHeaderPaidAt($type, $classHeaderPaidAt)
+ {
+ if (!empty($classHeaderPaidAt)) {
+ return $classHeaderPaidAt;
+ }
+
+ $class = $this->getClassFromConfig($type, 'header_due_at');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-md-2';
+ }
+
+ protected function getClassFooterHistories($type, $classFooterHistories)
+ {
+ if (!empty($classFooterHistories)) {
+ return $classFooterHistories;
+ }
+
+ $class = $this->getClassFromConfig($type, 'footer_histories');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-sm-6 col-md-6 col-lg-6 col-xl-6';
+ }
+
+ protected function getClassFooterTransactions($type, $classFooterTransactions)
+ {
+ if (!empty($classFooterTransactions)) {
+ return $classFooterTransactions;
+ }
+
+ $class = $this->getClassFromConfig($type, 'footer_transactions');
+
+ if (!empty($class)) {
+ return $class;
+ }
+
+ return 'col-sm-6 col-md-6 col-lg-6 col-xl-6';
+ }
+
+ protected function getHideName($type, $hideName)
+ {
+ if (!empty($hideName)) {
+ return $hideName;
+ }
+
+ // if you use settting translation
+ if ($hideName = setting($this->getSettingKey($type, 'hide_item_name'), false)) {
+ return $hideName;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'name');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_item_name', $hideName);
+ }
+
+ protected function getHideDescription($type, $hideDescription)
+ {
+ if (!empty($hideDescription)) {
+ return $hideDescription;
+ }
+
+ // if you use settting translation
+ if ($hideDescription = setting($this->getSettingKey($type, 'hide_item_description'), false)) {
+ return $hideDescription;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'description');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_item_description', $hideDescription);
+ }
+
+ protected function getHideAmount($type, $hideAmount)
+ {
+ if (!empty($hideAmount)) {
+ return $hideAmount;
+ }
+
+ // if you use settting translation
+ if ($hideAmount = setting($this->getSettingKey($type, 'hide_amount'), false)) {
+ return $hideAmount;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'amount');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_amount', $hideAmount);
+ }
+}
diff --git a/app/Abstracts/View/Components/TransactionTemplate.php b/app/Abstracts/View/Components/TransactionTemplate.php
new file mode 100644
index 000000000..c32f8fb14
--- /dev/null
+++ b/app/Abstracts/View/Components/TransactionTemplate.php
@@ -0,0 +1,653 @@
+type = $type;
+ $this->item = $item;
+ $this->transaction = $transaction;
+ $this->transactionTemplate = $this->gettransactionTemplate($type, $transactionTemplate);
+ $this->logo = $this->getLogo($logo);
+ $this->backgroundColor = $this->getBackgroundColor($type, $backgroundColor);
+
+ $this->payment_methods = ($payment_methods) ?: Modules::getPaymentMethods();
+
+ $this->hideFooter = $hideFooter;
+ $this->hideCompanyLogo = $hideCompanyLogo;
+ $this->hideCompanyDetails = $hideCompanyDetails;
+ $this->hideCompanyName = $hideCompanyName;
+ $this->hideCompanyAddress = $hideCompanyAddress;
+ $this->hideCompanyTaxNumber = $hideCompanyTaxNumber;
+ $this->hideCompanyPhone = $hideCompanyPhone;
+ $this->hideCompanyEmail = $hideCompanyEmail;
+ $this->hideContactInfo = $hideContactInfo;
+ $this->hideContactName = $hideContactName;
+ $this->hideContactAddress = $hideContactAddress;
+ $this->hideContactTaxNumber = $hideContactTaxNumber;
+ $this->hideContactPhone = $hideContactPhone;
+ $this->hideContactEmail = $hideContactEmail;
+ $this->hideOrderNumber = $hideOrderNumber;
+ $this->hidetransactionNumber = $hidetransactionNumber;
+ $this->hideIssuedAt = $hideIssuedAt;
+ $this->hideDueAt = $hideDueAt;
+
+ $this->texttransactionTitle = $this->getTexttransactionTitle($type, $texttransactionTitle);
+ $this->texttransactionSubheading = $this->gettexttransactionSubheading($type, $texttransactionSubheading);
+ $this->textContactInfo = $this->getTextContactInfo($type, $textContactInfo);
+ $this->textIssuedAt = $this->getTextIssuedAt($type, $textIssuedAt);
+ $this->texttransactionNumber = $this->getTexttransactionNumber($type, $texttransactionNumber);
+ $this->textDueAt = $this->getTextDueAt($type, $textDueAt);
+ $this->textOrderNumber = $this->getTextOrderNumber($type, $textOrderNumber);
+
+ $this->hideItems = $this->getHideItems($type, $hideItems, $hideName, $hideDescription);
+ $this->hideName = $this->getHideName($type, $hideName);
+ $this->hideDescription = $this->getHideDescription($type, $hideDescription);
+ $this->hideQuantity = $this->getHideQuantity($type, $hideQuantity);
+ $this->hidePrice = $this->getHidePrice($type, $hidePrice);
+ $this->hideDiscount = $this->getHideDiscount($type, $hideDiscount);
+ $this->hideAmount = $this->getHideAmount($type, $hideAmount);
+ $this->hideNote = $hideNote;
+
+ $this->textItems = $this->getTextItems($type, $textItems);
+ $this->textQuantity = $this->getTextQuantity($type, $textQuantity);
+ $this->textPrice = $this->getTextPrice($type, $textPrice);
+ $this->textAmount = $this->getTextAmount($type, $textAmount);
+ }
+
+ protected function gettransactionTemplate($type, $transactionTemplate)
+ {
+ if (!empty($transactionTemplate)) {
+ return $transactionTemplate;
+ }
+
+ if ($template = config('type.' . $type . 'template', false)) {
+ return $template;
+ }
+
+ $transactionTemplate = setting($this->getSettingKey($type, 'template'), 'default');
+
+ return $transactionTemplate;
+ }
+
+ protected function getLogo($logo)
+ {
+ if (!empty($logo)) {
+ return $logo;
+ }
+
+ $media = Media::find(setting('company.logo'));
+
+ if (!empty($media)) {
+ $path = $media->getDiskPath();
+
+ if (Storage::missing($path)) {
+ return $logo;
+ }
+ } else {
+ $path = base_path('public/img/company.png');
+ }
+
+ try {
+ $image = Image::cache(function($image) use ($media, $path) {
+ $width = setting('invoice.logo_size_width');
+ $height = setting('invoice.logo_size_height');
+
+ if ($media) {
+ $image->make(Storage::get($path))->resize($width, $height)->encode();
+ } else {
+ $image->make($path)->resize($width, $height)->encode();
+ }
+ });
+ } catch (NotReadableException | \Exception $e) {
+ Log::info('Company ID: ' . company_id() . ' components/transactionshow.php exception.');
+ Log::info($e->getMessage());
+
+ $path = base_path('public/img/company.png');
+
+ $image = Image::cache(function($image) use ($path) {
+ $width = setting('invoice.logo_size_width');
+ $height = setting('invoice.logo_size_height');
+
+ $image->make($path)->resize($width, $height)->encode();
+ });
+ }
+
+ if (empty($image)) {
+ return $logo;
+ }
+
+ $extension = File::extension($path);
+
+ return 'data:image/' . $extension . ';base64,' . base64_encode($image);
+ }
+
+ protected function getBackgroundColor($type, $backgroundColor)
+ {
+ if (!empty($backgroundColor)) {
+ return $backgroundColor;
+ }
+
+ if ($background_color = config('type.' . $type . 'color', false)) {
+ return $background_color;
+ }
+
+
+ if (!empty($alias = config('type.' . $type . '.alias'))) {
+ $type = $alias . '.' . str_replace('-', '_', $type);
+ }
+
+ $backgroundColor = setting($this->getSettingKey($type, 'color'), '#55588b');
+
+ return $backgroundColor;
+ }
+
+ protected function getTexttransactionTitle($type, $texttransactionTitle)
+ {
+ if (!empty($texttransactionTitle)) {
+ return $texttransactionTitle;
+ }
+
+ if (!empty(setting($type . '.title'))) {
+ return setting($type . '.title');
+ }
+
+ $translation = $this->getTextFromConfig($type, 'transaction_title', Str::plural($type));
+
+ if (!empty($translation)) {
+ return trans_choice($translation, 1);
+ }
+
+ return setting('invoice.title');
+ }
+
+ protected function getTexttransactionSubheading($type, $texttransactionSubheading)
+ {
+ if (!empty($texttransactionSubheading)) {
+ return $texttransactionSubheading;
+ }
+
+ if (!empty(setting($type . '.subheading'))) {
+ return setting($type . '.subheading');
+ }
+
+ $translation = $this->getTextFromConfig($type, 'transaction_subheading', 'subheading');
+
+ if (!empty($translation)) {
+ return trans($translation);
+ }
+
+ return false;
+ }
+
+ protected function getTexttransactionNumber($type, $texttransactionNumber)
+ {
+ if (!empty($texttransactionNumber)) {
+ return $texttransactionNumber;
+ }
+
+ switch ($type) {
+ case 'bill':
+ case 'expense':
+ case 'purchase':
+ $default_key = 'bill_number';
+ break;
+ default:
+ $default_key = 'invoice_number';
+ break;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'transaction_number', $default_key);
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.numbers';
+ }
+
+ protected function getTextOrderNumber($type, $textOrderNumber)
+ {
+ if (!empty($textOrderNumber)) {
+ return $textOrderNumber;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'order_number');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'invoices.order_number';
+ }
+
+ protected function getTextContactInfo($type, $textContactInfo)
+ {
+ if (!empty($textContactInfo)) {
+ return $textContactInfo;
+ }
+
+ switch ($type) {
+ case 'bill':
+ case 'expense':
+ case 'purchase':
+ $default_key = 'bill_from';
+ break;
+ default:
+ $default_key = 'bill_to';
+ break;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'contact_info', $default_key);
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'invoices.bill_to';
+ }
+
+ protected function getTextIssuedAt($type, $textIssuedAt)
+ {
+ if (!empty($textIssuedAt)) {
+ return $textIssuedAt;
+ }
+
+ switch ($type) {
+ case 'bill':
+ case 'expense':
+ case 'purchase':
+ $default_key = 'bill_date';
+ break;
+ default:
+ $default_key = 'invoice_date';
+ break;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'issued_at', $default_key);
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'invoices.invoice_date';
+ }
+
+ protected function getTextDueAt($type, $textDueAt)
+ {
+ if (!empty($textDueAt)) {
+ return $textDueAt;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'due_at', 'due_date');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'invoices.due_date';
+ }
+
+ protected function getTextItems($type, $textItems)
+ {
+ if (!empty($textItems)) {
+ return $textItems;
+ }
+
+ // if you use settting translation
+ if (setting($this->getSettingKey($type, 'item_name'), 'items') == 'custom') {
+ if (empty($textItems = setting($this->getSettingKey($type, 'item_name_input')))) {
+ $textItems = 'general.items';
+ }
+
+ return $textItems;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'items');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.items';
+ }
+
+ protected function getTextQuantity($type, $textQuantity)
+ {
+ if (!empty($textQuantity)) {
+ return $textQuantity;
+ }
+
+ // if you use settting translation
+ if (setting($this->getSettingKey($type, 'quantity_name'), 'quantity') === 'custom') {
+ if (empty($textQuantity = setting($this->getSettingKey($type, 'quantity_name_input')))) {
+ $textQuantity = 'invoices.quantity';
+ }
+
+ return $textQuantity;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'quantity');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'invoices.quantity';
+ }
+
+ protected function getTextPrice($type, $textPrice)
+ {
+ if (!empty($textPrice)) {
+ return $textPrice;
+ }
+
+ // if you use settting translation
+ if (setting($this->getSettingKey($type, 'price_name'), 'price') === 'custom') {
+ if (empty($textPrice = setting($this->getSettingKey($type, 'price_name_input')))) {
+ $textPrice = 'invoices.price';
+ }
+
+ return $textPrice;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'price');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'invoices.price';
+ }
+
+ protected function getTextAmount($type, $textAmount)
+ {
+ if (!empty($textAmount)) {
+ return $textAmount;
+ }
+
+ $translation = $this->getTextFromConfig($type, 'amount');
+
+ if (!empty($translation)) {
+ return $translation;
+ }
+
+ return 'general.amount';
+ }
+
+ protected function getHideItems($type, $hideItems, $hideName, $hideDescription)
+ {
+ if (!empty($hideItems)) {
+ return $hideItems;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'items');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ $hideItems = ($this->getHideName($type, $hideName) & $this->getHideDescription($type, $hideDescription)) ? true : false;
+
+ return $hideItems;
+ }
+
+ protected function getHideName($type, $hideName)
+ {
+ if (!empty($hideName)) {
+ return $hideName;
+ }
+
+ // if you use settting translation
+ if ($hideName = setting($this->getSettingKey($type, 'hide_item_name'), false)) {
+ return $hideName;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'name');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_item_name', $hideName);
+ }
+
+ protected function getHideDescription($type, $hideDescription)
+ {
+ if (!empty($hideDescription)) {
+ return $hideDescription;
+ }
+
+ // if you use settting translation
+ if ($hideDescription = setting($this->getSettingKey($type, 'hide_item_description'), false)) {
+ return $hideDescription;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'description');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_item_description', $hideDescription);
+ }
+
+ protected function getHideQuantity($type, $hideQuantity)
+ {
+ if (!empty($hideQuantity)) {
+ return $hideQuantity;
+ }
+
+ // if you use settting translation
+ if ($hideQuantity = setting($this->getSettingKey($type, 'hide_quantity'), false)) {
+ return $hideQuantity;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'quantity');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_quantity', $hideQuantity);
+ }
+
+ protected function getHidePrice($type, $hidePrice)
+ {
+ if (!empty($hidePrice)) {
+ return $hidePrice;
+ }
+
+ // if you use settting translation
+ if ($hidePrice = setting($this->getSettingKey($type, 'hide_price'), false)) {
+ return $hidePrice;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'price');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_price', $hidePrice);
+ }
+
+ protected function getHideDiscount($type, $hideDiscount)
+ {
+ if (!empty($hideDiscount)) {
+ return $hideDiscount;
+ }
+
+ // if you use settting translation
+ if ($hideDiscount = setting($this->getSettingKey($type, 'hide_discount'), false)) {
+ return $hideDiscount;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'discount');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_discount', $hideDiscount);
+ }
+
+ protected function getHideAmount($type, $hideAmount)
+ {
+ if (!empty($hideAmount)) {
+ return $hideAmount;
+ }
+
+ // if you use settting translation
+ if ($hideAmount = setting($this->getSettingKey($type, 'hide_amount'), false)) {
+ return $hideAmount;
+ }
+
+ $hide = $this->getHideFromConfig($type, 'amount');
+
+ if ($hide) {
+ return $hide;
+ }
+
+ // @todo what return value invoice or always false??
+ return setting('invoice.hide_amount', $hideAmount);
+ }
+}
diff --git a/app/Events/Transaction/TransactionPrinting.php b/app/Events/Transaction/TransactionPrinting.php
new file mode 100644
index 000000000..602e02f60
--- /dev/null
+++ b/app/Events/Transaction/TransactionPrinting.php
@@ -0,0 +1,22 @@
+transaction = $transaction;
+ }
+}
diff --git a/app/Events/Transaction/TransactionSent.php b/app/Events/Transaction/TransactionSent.php
new file mode 100644
index 000000000..1ab92798e
--- /dev/null
+++ b/app/Events/Transaction/TransactionSent.php
@@ -0,0 +1,20 @@
+transaction = $transaction;
+ }
+}
diff --git a/app/Http/Controllers/Purchases/Payments.php b/app/Http/Controllers/Purchases/Payments.php
index de34559dc..acc9674f8 100644
--- a/app/Http/Controllers/Purchases/Payments.php
+++ b/app/Http/Controllers/Purchases/Payments.php
@@ -257,4 +257,69 @@ class Payments extends Controller
{
return $this->exportExcel(new Export, trans_choice('general.payments', 2));
}
+
+ /**
+ * Download the PDF file of payment.
+ *
+ * @param Transaction $payment
+ *
+ * @return Response
+ */
+ public function emailPayment(Transaction $payment)
+ {
+ if (empty($payment->contact->email)) {
+ return redirect()->back();
+ }
+
+ // Notify the customer
+ $payment->contact->notify(new Notification($payment, 'payment_new_customer', true));
+
+ event(new \App\Events\Transaction\TransactionSent($payment));
+
+ flash(trans('documents.messages.email_sent', ['type' => trans_choice('general.payments', 1)]))->success();
+
+ return redirect()->back();
+ }
+
+ /**
+ * Print the payment.
+ *
+ * @param Transaction $payment
+ *
+ * @return Response
+ */
+ public function printPayment(Transaction $payment)
+ {
+ event(new \App\Events\Transaction\TransactionPrinting($payment));
+
+ $view = view($payment->template_path, compact('payment'));
+
+ return mb_convert_encoding($view, 'HTML-ENTITIES', 'UTF-8');
+ }
+
+ /**
+ * Download the PDF file of payment.
+ *
+ * @param Transaction $payment
+ *
+ * @return Response
+ */
+ public function pdfPayment(Transaction $payment)
+ {
+ event(new \App\Events\Transaction\TransactionPrinting($payment));
+
+ $currency_style = true;
+
+ $view = view($payment->template_path, compact('payment', 'currency_style'))->render();
+ $html = mb_convert_encoding($view, 'HTML-ENTITIES', 'UTF-8');
+
+ $pdf = app('dompdf.wrapper');
+ $pdf->loadHTML($html);
+
+ //$pdf->setPaper('A4', 'portrait');
+
+ $file_name = $this->getDocumentFileName($payment);
+
+ return $pdf->download($file_name);
+ }
}
diff --git a/app/Http/Controllers/Sales/Revenues.php b/app/Http/Controllers/Sales/Revenues.php
index 463f04ff3..ffe39ade6 100644
--- a/app/Http/Controllers/Sales/Revenues.php
+++ b/app/Http/Controllers/Sales/Revenues.php
@@ -257,4 +257,69 @@ class Revenues extends Controller
{
return $this->exportExcel(new Export, trans_choice('general.revenues', 2));
}
+
+ /**
+ * Download the PDF file of revenue.
+ *
+ * @param Transaction $revenue
+ *
+ * @return Response
+ */
+ public function emailRevenue(Transaction $revenue)
+ {
+ if (empty($revenue->contact->email)) {
+ return redirect()->back();
+ }
+
+ // Notify the customer
+ $revenue->contact->notify(new Notification($revenue, 'revenue_new_customer', true));
+
+ event(new \App\Events\Transaction\TransactionSent($revenue));
+
+ flash(trans('documents.messages.email_sent', ['type' => trans_choice('general.revenues', 1)]))->success();
+
+ return redirect()->back();
+ }
+
+ /**
+ * Print the revenue.
+ *
+ * @param Transaction $revenue
+ *
+ * @return Response
+ */
+ public function printRevenue(Transaction $revenue)
+ {
+ event(new \App\Events\Transaction\TransactionPrinting($revenue));
+
+ $view = view($revenue->template_path, compact('revenue'));
+
+ return mb_convert_encoding($view, 'HTML-ENTITIES', 'UTF-8');
+ }
+
+ /**
+ * Download the PDF file of revenue.
+ *
+ * @param Transaction $revenue
+ *
+ * @return Response
+ */
+ public function pdfRevenue(Transaction $revenue)
+ {
+ event(new \App\Events\Transaction\TransactionPrinting($revenue));
+
+ $currency_style = true;
+
+ $view = view($revenue->template_path, compact('revenue', 'currency_style'))->render();
+ $html = mb_convert_encoding($view, 'HTML-ENTITIES', 'UTF-8');
+
+ $pdf = app('dompdf.wrapper');
+ $pdf->loadHTML($html);
+
+ //$pdf->setPaper('A4', 'portrait');
+
+ $file_name = $this->getDocumentFileName($revenue);
+
+ return $pdf->download($file_name);
+ }
}
diff --git a/app/Models/Banking/Transaction.php b/app/Models/Banking/Transaction.php
index ca039c12d..89b1f5440 100644
--- a/app/Models/Banking/Transaction.php
+++ b/app/Models/Banking/Transaction.php
@@ -391,6 +391,11 @@ class Transaction extends Model
return !empty($value) ? $value : (!empty($this->document_id) ? $this->document_id : $this->id);
}
+ public function getTemplatePathAttribute($value = null)
+ {
+ return $value ?: 'sales.revenues.print_default';
+ }
+
/**
* Create a new factory instance for the model.
*
diff --git a/app/Traits/Transactions.php b/app/Traits/Transactions.php
index d70e2b22e..c3d040418 100644
--- a/app/Traits/Transactions.php
+++ b/app/Traits/Transactions.php
@@ -59,4 +59,20 @@ trait Transactions
'transaction.type.' . $index => implode(',', $types),
])->save();
}
+
+ protected function getSettingKey($type, $setting_key)
+ {
+ $key = '';
+ $alias = config('type.' . $type . '.alias');
+
+ if (!empty($alias)) {
+ $key .= $alias . '.';
+ }
+
+ $prefix = config('type.' . $type . '.setting.prefix');
+
+ $key .= $prefix . '.' . $setting_key;
+
+ return $key;
+ }
}
diff --git a/app/View/Components/Transactions/Script.php b/app/View/Components/Transactions/Script.php
new file mode 100644
index 000000000..c78ede332
--- /dev/null
+++ b/app/View/Components/Transactions/Script.php
@@ -0,0 +1,55 @@
+type = $type;
+ $this->scriptFile = ($scriptFile) ? $scriptFile : 'public/js/common/documents.js';
+ $this->version = $this->getVersion($version);
+ $this->transaction = $transaction;
+ }
+
+ /**
+ * Get the view / contents that represent the component.
+ *
+ * @return \Illuminate\Contracts\View\View|string
+ */
+ public function render()
+ {
+ return view('components.transactions.script');
+ }
+
+ protected function getVersion($version)
+ {
+ if (!empty($version)) {
+ return $version;
+ }
+
+ if ($alias = config('type.' . $this->type . '.alias')) {
+ return module_version($alias);
+ }
+
+ return version('short');
+ }
+}
diff --git a/app/View/Components/Transactions/Show/Attachment.php b/app/View/Components/Transactions/Show/Attachment.php
new file mode 100644
index 000000000..2e9e2c339
--- /dev/null
+++ b/app/View/Components/Transactions/Show/Attachment.php
@@ -0,0 +1,18 @@
+ [
'group' => 'sales',
+ 'route' => [
+ 'prefix' => 'revenues', // core use with group + prefix, module ex. estimates
+ 'parameter' => 'revenue', // sales/invoices/{parameter}/edit
+ //'create' => 'invoices.create', // if you change route, you can write full path
+ ],
'permission' => [
'prefix' => 'revenues',
//'create' => 'create-sales-revenues',
],
+ 'translation' => [
+ 'prefix' => 'revenues', // this translation file name.
+ ],
'contact_type' => 'customer',
],
'expense' => [
'group' => 'purchases',
+ 'route' => [
+ 'prefix' => 'payments', // core use with group + prefix, module ex. estimates
+ 'parameter' => 'payment', // sales/invoices/{parameter}/edit
+ //'create' => 'invoices.create', // if you change route, you can write full path
+ ],
'permission' => [
'prefix' => 'payments',
//'create' => 'create-purchases-payments',
],
+ 'translation' => [
+ 'prefix' => 'payments', // this translation file name.
+ ],
'contact_type' => 'vendor',
],
diff --git a/resources/views/components/transactions/script.blade.php b/resources/views/components/transactions/script.blade.php
new file mode 100644
index 000000000..4bb9715dd
--- /dev/null
+++ b/resources/views/components/transactions/script.blade.php
@@ -0,0 +1 @@
+
diff --git a/resources/views/components/transactions/show/attachment.blade.php b/resources/views/components/transactions/show/attachment.blade.php
new file mode 100644
index 000000000..6ab858a27
--- /dev/null
+++ b/resources/views/components/transactions/show/attachment.blade.php
@@ -0,0 +1,9 @@
+@if ($attachment)
+
+ @foreach ($attachment as $file)
+
+ @include('partials.media.file')
+
+ @endforeach
+
+@endif
diff --git a/resources/views/components/transactions/show/content.blade.php b/resources/views/components/transactions/show/content.blade.php
new file mode 100644
index 000000000..844a86cad
--- /dev/null
+++ b/resources/views/components/transactions/show/content.blade.php
@@ -0,0 +1,58 @@
+@stack('content_header_start')
+@if (!$hideHeader)
+
+@endif
+@stack('content_header_end')
+
+@stack('transaction_start')
+
+@stack('transaction_end')
+
+@stack('attachment_start')
+ @if (!$hideAttachment)
+
+ @endif
+@stack('attachment_end')
+
+@stack('row_footer_start')
+ @if (!$hideFooter)
+
+ @endif
+@stack('row_footer_end')
+
+{{ Form::hidden('transaction_id', $transaction->id, ['id' => 'transaction_id']) }}
+{{ Form::hidden($type . '_id', $transaction->id, ['id' => $type . '_id']) }}
diff --git a/resources/views/components/transactions/show/footer.blade.php b/resources/views/components/transactions/show/footer.blade.php
new file mode 100644
index 000000000..3bae7fad0
--- /dev/null
+++ b/resources/views/components/transactions/show/footer.blade.php
@@ -0,0 +1,14 @@
+
+ @stack('row_footer_histories_start')
+ @if (!$hideFooterHistories)
+
+ @endif
+ @stack('row_footer_histories_end')
+
diff --git a/resources/views/components/transactions/show/header.blade.php b/resources/views/components/transactions/show/header.blade.php
new file mode 100644
index 000000000..b74d978ca
--- /dev/null
+++ b/resources/views/components/transactions/show/header.blade.php
@@ -0,0 +1,81 @@
+
+ @stack('header_account_start')
+ @if (!$hideHeaderAccount)
+
+ @endif
+ @stack('header_account_end')
+
+ @stack('header_category_start')
+ @if (!$hideHeaderCategory)
+
+ @endif
+ @stack('header_category_end')
+
+ @stack('header_contact_start')
+ @if (!$hideHeaderContact)
+
+ @endif
+ @stack('header_contact_end')
+
+ @stack('header_amount_start')
+ @if (!$hideHeaderAmount)
+
+ @endif
+ @stack('header_amount_end')
+
+ @stack('header_paid_at_start')
+ @if (!$hideHeaderPaidAt)
+
+ @endif
+ @stack('header_paid_at_end')
+
diff --git a/resources/views/components/transactions/show/histories.blade.php b/resources/views/components/transactions/show/histories.blade.php
new file mode 100644
index 000000000..95b31c0d7
--- /dev/null
+++ b/resources/views/components/transactions/show/histories.blade.php
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+ @stack('row_footer_histories_head_tr_start')
+
+ @stack('row_footer_histories_head_start')
+ |
+ {{ trans('general.date') }}
+ |
+
+
+ {{ trans('general.description') }}
+ |
+ @stack('row_footer_histories_head_end')
+
+ @stack('row_footer_histories_head_tr_end')
+
+
+
+ @stack('row_footer_histories_body_tr_start')
+ @foreach($histories as $history)
+
+ @stack('row_footer_histories_body_td_start')
+ |
+ @date($history->created_at)
+ |
+
+
+ {{ $history->description }}
+ |
+ @stack('row_footer_histories_body_td_end')
+
+ @endforeach
+ @stack('row_footer_histories_body_tr_end')
+
+
+
+
+
+
diff --git a/resources/views/components/transactions/show/top-buttons.blade.php b/resources/views/components/transactions/show/top-buttons.blade.php
new file mode 100644
index 000000000..9481840e9
--- /dev/null
+++ b/resources/views/components/transactions/show/top-buttons.blade.php
@@ -0,0 +1,109 @@
+@stack('button_group_start')
+@if (!$hideButtonMoreActions)
+
+@endif
+@stack('button_group_end')
+
+@stack('add_new_button_start')
+@if (!$hideButtonAddNew)
+ @can($permissionCreate)
+
+ {{ trans('general.add_new') }}
+
+ @endcan
+@endif
+@stack('add_new_button_end')
diff --git a/resources/views/components/transactions/show/transaction.blade.php b/resources/views/components/transactions/show/transaction.blade.php
new file mode 100644
index 000000000..c682814ff
--- /dev/null
+++ b/resources/views/components/transactions/show/transaction.blade.php
@@ -0,0 +1,22 @@
+
+
+ @if ($transactionTemplate)
+ @switch($transactionTemplate)
+ @case('classic')
+ @break
+ @case('modern')
+ @break
+ @default
+
+ @endswitch
+ @else
+ @include($transactionTemplate)
+ @endif
+
+
diff --git a/resources/views/components/transactions/template/default.blade.php b/resources/views/components/transactions/template/default.blade.php
new file mode 100644
index 000000000..b89e0c7e7
--- /dev/null
+++ b/resources/views/components/transactions/template/default.blade.php
@@ -0,0 +1,247 @@
+
+
+
+ @stack('company_logo_start')
+ @if (!$hideCompanyLogo)
+ @if (!empty($document->contact->logo) && !empty($document->contact->logo->id))
+
 }})
+ @else
+

+ @endif
+ @endif
+ @stack('company_logo_end')
+
+
+
+
+
+ @stack('company_details_start')
+ @if (!$hideCompanyDetails)
+ @if (!$hideCompanyName)
+
+ {{ setting('company.name') }}
+
+ @endif
+
+ @if (!$hideCompanyAddress)
+
{!! nl2br(setting('company.address')) !!}
+ @endif
+
+ @if (!$hideCompanyTaxNumber)
+
+ @if (setting('company.tax_number'))
+ {{ trans('general.tax_number') }}: {{ setting('company.tax_number') }}
+ @endif
+
+ @endif
+
+ @if (!$hideCompanyPhone)
+
+ @if (setting('company.phone'))
+ {{ setting('company.phone') }}
+ @endif
+
+ @endif
+
+ @if (!$hideCompanyEmail)
+
{{ setting('company.email') }}
+ @endif
+ @endif
+ @stack('company_details_end')
+
+
+
+
+
+
{{ trans('invoices.revenue_made') }}
+
+
+
+
+
+
+ {{ trans('general.date') }}:
+
+
+
+ {{ trans_choice('general.accounts', 1) }}:
+
+
+
+ {{ trans_choice('general.categories', 1) }}:
+
+
+
+ {{ trans_choice('general.payment_methods', 1) }}:
+
+
+
+ {{ trans('general.reference') }}:
+
+
+
+ {{ trans('general.description') }}:
+
+
+
+
+
+ @date($transaction->paid_at)
+
+
+
+ {{ $transaction->account->name }}
+
+
+
+ {{ $transaction->category->name }}
+
+
+
+ {{ $payment_methods[$transaction->payment_method] }}
+
+
+
+ {{ $transaction->reference }}
+
+
+
+ {!! nl2br($transaction->description) !!}
+
+
+
+
+
+
{{ trans('general.paid_by') }}
+
+ @if ($hideContactInfo)
+
{{ trans($textContactInfo) }}
+ @endif
+
+ @stack('name_input_start')
+ @if (!$hideContactName)
+
{{ $transaction->contact->name }}
+ @endif
+ @stack('name_input_end')
+
+ @stack('address_input_start')
+ @if (!$hideContactAddress)
+
{!! nl2br($transaction->contact->address) !!}
+ @endif
+ @stack('address_input_end')
+
+ @stack('tax_number_input_start')
+ @if (!$hideContactTaxNumber)
+
+ @if ($transaction->contact->tax_number)
+ {{ trans('general.tax_number') }}: {{ $transaction->contact->tax_number }}
+ @endif
+
+ @endif
+ @stack('tax_number_input_end')
+
+ @stack('phone_input_start')
+ @if (!$hideContactPhone)
+
+ @if ($transaction->contact->phone)
+ {{ $transaction->contact->phone }}
+ @endif
+
+ @endif
+ @stack('phone_input_end')
+
+ @stack('email_start')
+ @if (!$hideContactEmail)
+
+ {{ $transaction->contact->email }}
+
+ @endif
+ @stack('email_input_end')
+
+
+
+
+
+
+
+
+
{{ trans('general.amount') }}
+
+
+ @money($transaction->amount, $transaction->currency_code, true)
+
+
+
+
+
+
+
+
+
+@if ($transaction->document)
+
+
+
+
{{ trans('invoices.related_revenue') }}
+
+
+
+
+ |
+ {{ trans_choice('general.numbers', 1) }}
+ |
+
+
+ {{ trans_choice('general.customers', 1) }}
+ |
+
+
+ {{ trans('invoices.invoice_date') }}
+ |
+
+
+ {{ trans('invoices.invoice_date') }}
+ |
+
+
+ {{ trans('general.amount') }}
+ |
+
+
+
+
+
+ |
+
+ {{ $transaction->document->document_number }}
+
+ |
+
+
+ {{ $transaction->document->contact_name }}
+ |
+
+
+ @date($transaction->document->due_at)
+ |
+
+
+ @money($transaction->document->amount, $transaction->document->currency_code, true)
+ |
+
+
+ @money($transaction->amount, $transaction->currency_code, true)
+ |
+
+
+
+
+
+
+@else
+
+
+ {{ trans('invoices.overdue_revenue') }}: @money($transaction->amount, $transaction->currency_code, true)
+
+
+@endif
\ No newline at end of file
diff --git a/resources/views/purchases/payments/show.blade.php b/resources/views/purchases/payments/show.blade.php
index 9f992b02a..892f0b288 100644
--- a/resources/views/purchases/payments/show.blade.php
+++ b/resources/views/purchases/payments/show.blade.php
@@ -1,180 +1,17 @@
@extends('layouts.admin')
-@section('title', trans('bills.payment_made') )
+@section('title', trans('invoices.payment_made'))
@section('new_button')
-@can('create-sales-revenues')
-
-{{ trans('general.add_new') }}
-@endcan
+
@endsection
@section('content')
-
-
-
-
-
- {{ trans_choice('general.accounts', 1) }}
-
- Account name
-
-
-
- {{ trans_choice('general.categories', 1) }}
-
- Category name
-
-
-
- {{ trans_choice('general.vendors', 1) }}
-
- Vendor name
-
-
- {{ trans('general.amount') }}
-
- {{ $payment->amount }}
-
-
- {{ trans('general.date') }}
-
- {{ Date::parse($payment->paid_at)->toDateString() }}
-
-
-
-
-
-
-
-
-
{{ trans_choice('bills.payment_made', 1) }}
-
-
-
-
-
{{ trans('general.date') }}:
-
-
{{ trans_choice('general.accounts', 1) }}:
-
-
{{ trans_choice('general.categories', 1) }}:
-
{{ trans_choice('general.payment_methods', 1) }}:
-
{{ trans('general.reference') }}:
-
{{ trans('general.description') }}:
-
-
-
12.12.2022
-
-
Account One
-
Data Category
-
Cash
-
Lorem Ipsum
-
Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
-
-
-
-
{{ trans('general.paid_to') }}
-
-
Adress
-
-
-
-
-
-
-
-
{{ trans('general.amount') }}
- ₺0,00
-
-
-
-
-
-
-
-
-
-
-
-
{{ trans('bills.related_bill') }}
-
-
-
- | {{ trans('bills.bill_number') }} |
- {{ trans_choice('general.vendors', 1) }} |
- {{ trans('bills.bill_date') }} |
- {{ trans('general.amount') }} |
-
-
-
-
- | BILL-123 |
- Vendor name |
- 12.12.2022 |
- ₺6.000,00 |
-
-
-
-
-
-
-
-
{{ trans('bills.overdue_payment') }}: ₺6.000,00
-
-
-
-
-
-
-
-
-
-
-
-
- | {{ trans('general.revenue_date') }} |
- {{ trans('general.created') }} |
-
-
-
-
- |
- 12.12.2022
- |
-
- Created name
- |
-
-
-
-
-
-
-
-
-
-
+
@endsection
@push('scripts_start')
-
+
-
-@endpush
\ No newline at end of file
+
+@endpush
diff --git a/resources/views/sales/revenues/show.blade.php b/resources/views/sales/revenues/show.blade.php
index f2c332c93..a6dcdefa8 100644
--- a/resources/views/sales/revenues/show.blade.php
+++ b/resources/views/sales/revenues/show.blade.php
@@ -3,178 +3,15 @@
@section('title', trans('invoices.revenue_made'))
@section('new_button')
-@can('create-sales-revenues')
-
-{{ trans('general.add_new') }}
-@endcan
+
@endsection
@section('content')
-
-
-
-
-
- {{ trans_choice('general.accounts', 1) }}
-
- Account name
-
-
-
- {{ trans_choice('general.categories', 1) }}
-
- Category name
-
-
-
- {{ trans_choice('general.customers', 1) }}
-
- Customer name
-
-
- {{ trans('general.amount') }}
-
-
-
-
- {{ trans('general.date') }}
-
-
-
-
-
-
-
-
-
-
-
{{ trans('invoices.revenue_made') }}
-
-
-
-
-
{{ trans('general.date') }}:
-
-
{{ trans_choice('general.accounts', 1) }}:
-
-
{{ trans_choice('general.categories', 1) }}:
-
{{ trans_choice('general.payment_methods', 1) }}:
-
{{ trans('general.reference') }}:
-
{{ trans('general.description') }}:
-
-
-
12.12.2022
-
-
Account One
-
Data Category
-
Cash
-
Lorem Ipsum
-
Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum Lorem Ipsum
-
-
-
-
{{ trans('general.paid_by') }}
-
-
Adress
-
-
-
-
-
-
-
-
{{ trans('general.amount') }}
- ₺0,00
-
-
-
-
-
-
-
-
-
-
-
-
{{ trans('invoices.related_revenue') }}
-
-
-
- | {{ trans_choice('general.numbers', 1) }} |
- {{ trans_choice('general.customers', 1) }} |
- {{ trans('invoices.invoice_date') }} |
- {{ trans('general.amount') }} |
-
-
-
-
- | BILL-123 |
- Vendor name |
- 12.12.2022 |
- ₺6.000,00 |
-
-
-
-
-
-
-
-
{{ trans('invoices.overdue_revenue') }}: ₺6.000,00
-
-
-
-
-
-
-
-
-
-
-
-
- | {{ trans('general.revenue_date') }} |
- {{ trans('general.created') }} |
-
-
-
-
- |
- 12.12.2022
- |
-
- Created name
- |
-
-
-
-
-
-
-
-
-
-
+
@endsection
@push('scripts_start')
-
+
-
+
@endpush
diff --git a/routes/admin.php b/routes/admin.php
index 63863782f..69765e0b3 100644
--- a/routes/admin.php
+++ b/routes/admin.php
@@ -81,6 +81,9 @@ Route::group(['prefix' => 'sales'], function () {
Route::get('invoices/export', 'Sales\Invoices@export')->name('invoices.export');
Route::resource('invoices', 'Sales\Invoices', ['middleware' => ['date.format', 'money', 'dropzone']]);
+ Route::get('revenues/{revenue}/email', 'Sales\Revenues@emailRevenue')->name('revenues.email');
+ Route::get('revenues/{revenue}/print', 'Sales\Revenues@printRevenue')->name('revenues.print');
+ Route::get('revenues/{revenue}/pdf', 'Sales\Revenues@pdfRevenue')->name('revenues.pdf');
Route::get('revenues/{revenue}/duplicate', 'Sales\Revenues@duplicate')->name('revenues.duplicate');
Route::post('revenues/import', 'Sales\Revenues@import')->name('revenues.import');
Route::get('revenues/export', 'Sales\Revenues@export')->name('revenues.export');
@@ -108,6 +111,9 @@ Route::group(['prefix' => 'purchases'], function () {
Route::get('bills/export', 'Purchases\Bills@export')->name('bills.export');
Route::resource('bills', 'Purchases\Bills', ['middleware' => ['date.format', 'money', 'dropzone']]);
+ Route::get('payments/{payment}/email', 'Purchases\Payments@emailPayment')->name('payments.email');
+ Route::get('payments/{payment}/print', 'Purchases\Payments@printPayment')->name('payments.print');
+ Route::get('payments/{payment}/pdf', 'Purchases\Payments@pdfPayment')->name('payments.pdf');
Route::get('payments/{payment}/duplicate', 'Purchases\Payments@duplicate')->name('payments.duplicate');
Route::post('payments/import', 'Purchases\Payments@import')->name('payments.import');
Route::get('payments/export', 'Purchases\Payments@export')->name('payments.export');
diff --git a/routes/signed.php b/routes/signed.php
index 9d02774e6..0d9481b33 100644
--- a/routes/signed.php
+++ b/routes/signed.php
@@ -14,3 +14,7 @@ Route::get('invoices/{invoice}/print', 'Portal\Invoices@printInvoice')->name('si
Route::get('invoices/{invoice}/pdf', 'Portal\Invoices@pdfInvoice')->name('signed.invoices.pdf');
Route::post('invoices/{invoice}/payment', 'Portal\Invoices@payment')->name('signed.invoices.payment');
Route::post('invoices/{invoice}/confirm', 'Portal\Invoices@confirm')->name('signed.invoices.confirm');
+
+Route::get('payments/{payment}', 'Portal\Payments@signed')->name('signed.payments.show');
+Route::get('payments/{payment}/print', 'Portal\Payments@printInvoice')->name('signed.payments.print');
+Route::get('payments/{payment}/pdf', 'Portal\Payments@pdfInvoice')->name('signed.payments.pdf');