diff --git a/app/DataMapper/InvoiceItem.php b/app/DataMapper/InvoiceItem.php index bf7b1513bffa..60d1c0ee4ca4 100644 --- a/app/DataMapper/InvoiceItem.php +++ b/app/DataMapper/InvoiceItem.php @@ -64,7 +64,9 @@ class InvoiceItem public $task_id = ''; public $expense_id = ''; - + + public $unit_code = 'C62'; + public static $casts = [ 'task_id' => 'string', 'expense_id' => 'string', @@ -92,5 +94,6 @@ class InvoiceItem 'custom_value2' => 'string', 'custom_value3' => 'string', 'custom_value4' => 'string', + 'unit_code' => 'string', ]; } diff --git a/app/Http/Controllers/PurchaseOrderController.php b/app/Http/Controllers/PurchaseOrderController.php index 1682380e02f1..4b5fa3981b3b 100644 --- a/app/Http/Controllers/PurchaseOrderController.php +++ b/app/Http/Controllers/PurchaseOrderController.php @@ -646,7 +646,6 @@ class PurchaseOrderController extends BaseController echo $file; }, $purchase_order->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']); - break; case 'restore': $this->purchase_order_repository->restore($purchase_order); diff --git a/app/Jobs/Entity/CreateRawPdf.php b/app/Jobs/Entity/CreateRawPdf.php index bb5a37001283..ac4320f1a89d 100644 --- a/app/Jobs/Entity/CreateRawPdf.php +++ b/app/Jobs/Entity/CreateRawPdf.php @@ -88,6 +88,7 @@ class CreateRawPdf 'quote' => $type = 'product', 'credit' => $type = 'product', 'recurring_invoice' => $type = 'product', + default => $type = 'product', }; return $type; diff --git a/app/Models/Expense.php b/app/Models/Expense.php index 95be95a9123f..126e405ed03b 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -190,7 +190,7 @@ class Expense extends BaseModel public function purchase_order() { - return $this->hasOne(PurchaseOrder::class); + return $this->hasOne(PurchaseOrder::class)->withTrashed(); } public function translate_entity() diff --git a/app/Models/PurchaseOrder.php b/app/Models/PurchaseOrder.php index 3cc2b0e0de3b..284c211f56b5 100644 --- a/app/Models/PurchaseOrder.php +++ b/app/Models/PurchaseOrder.php @@ -265,7 +265,7 @@ class PurchaseOrder extends BaseModel public function expense(): \Illuminate\Database\Eloquent\Relations\BelongsTo { - return $this->belongsTo(Expense::class); + return $this->belongsTo(Expense::class)->withTrashed(); } public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Repositories/ActivityRepository.php b/app/Repositories/ActivityRepository.php index 35465a3acf7a..09c530d7ad1b 100644 --- a/app/Repositories/ActivityRepository.php +++ b/app/Repositories/ActivityRepository.php @@ -41,7 +41,7 @@ class ActivityRepository extends BaseRepository * Save the Activity. * * @param \stdClass $fields The fields - * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder $entity + * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder | \App\Models\Expense $entity * @param array $event_vars */ public function save($fields, $entity, $event_vars) @@ -72,7 +72,7 @@ class ActivityRepository extends BaseRepository /** * Creates a backup. * - * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder $entity + * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder | \App\Models\Expense $entity * @param \App\Models\Activity $activity The activity */ public function createBackup($entity, $activity) diff --git a/app/Repositories/ExpenseRepository.php b/app/Repositories/ExpenseRepository.php index 5b87af81466d..b9d125045fff 100644 --- a/app/Repositories/ExpenseRepository.php +++ b/app/Repositories/ExpenseRepository.php @@ -46,10 +46,12 @@ class ExpenseRepository extends BaseRepository /** @var \App\Models\User $user */ $user = auth()->user(); - if(isset($data['payment_date']) && $data['payment_date'] == $expense->payment_date) { + $payment_date = &$data['payment_date']; + $vendor_id = &$data['vendor_id']; + + if($payment_date && $payment_date == $expense->payment_date) { //do nothing - } elseif(isset($data['payment_date']) && strlen($data['payment_date']) > 1 && $user->company()->notify_vendor_when_paid && (isset($data['vendor_id']) || $expense->vendor_id)) { - nlog("ping"); + } elseif($payment_date && strlen($payment_date) > 1 && $user->company()->notify_vendor_when_paid && ($vendor_id || $expense->vendor_id)) { $this->notify_vendor = true; } @@ -73,6 +75,13 @@ class ExpenseRepository extends BaseRepository VendorExpenseNotify::dispatch($expense, $expense->company->db); } + if($payment_date && strlen($payment_date) > 1 && $expense->purchase_order) { + $purchase_order = $expense->purchase_order; + $purchase_order->balance = round($purchase_order->amount - $expense->amount, 2); + $purchase_order->paid_to_date = $expense->amount; + $purchase_order->save(); + } + return $expense; } diff --git a/app/Services/EDocument/Standards/RoEInvoice.php b/app/Services/EDocument/Standards/RoEInvoice.php index eae2951aee42..6cdf2885d731 100644 --- a/app/Services/EDocument/Standards/RoEInvoice.php +++ b/app/Services/EDocument/Standards/RoEInvoice.php @@ -31,6 +31,7 @@ use CleverIt\UBL\Invoice\TaxCategory; use CleverIt\UBL\Invoice\TaxScheme; use CleverIt\UBL\Invoice\TaxSubTotal; use CleverIt\UBL\Invoice\TaxTotal; +use App\Models\Product; class RoEInvoice extends AbstractService { @@ -130,7 +131,7 @@ class RoEInvoice extends AbstractService ->setTaxAmount($invoicing_data->getItemTotalTaxes()) ->setTaxableAmount($taxable) ->setTaxCategory((new TaxCategory()) - ->setId(explode('-', $company->settings->custom_value3)[0]) + ->setId("S") ->setPercent($taxRatePercent) ->setTaxScheme(($taxNameScheme === 'TVA') ? 'VAT' : $taxNameScheme))); $ubl_invoice->setTaxTotal($taxtotal); @@ -212,29 +213,29 @@ class RoEInvoice extends AbstractService { if (strlen($item->tax_name1) > 1) { $classifiedTaxCategory = (new ClassifiedTaxCategory()) - ->setId(explode('-', $item->custom_value4)[0]) + ->setId($this->resolveTaxCode($item->tax_id ?? 1)) ->setPercent($item->tax_rate1) ->setTaxScheme(($item->tax_name1 === 'TVA') ? 'VAT' : $item->tax_name1); } elseif (strlen($item->tax_name2) > 1) { $classifiedTaxCategory = (new ClassifiedTaxCategory()) - ->setId(explode('-', $item->custom_value4)[0]) + ->setId($this->resolveTaxCode($item->tax_id ?? 1)) ->setPercent($item->tax_rate2) ->setTaxScheme(($item->tax_name2 === 'TVA') ? 'VAT' : $item->tax_name2); } elseif (strlen($item->tax_name3) > 1) { $classifiedTaxCategory = (new ClassifiedTaxCategory()) - ->setId(explode('-', $item->custom_value4)[0]) + ->setId($this->resolveTaxCode($item->tax_id ?? 1)) ->setPercent($item->tax_rate3) ->setTaxScheme(($item->tax_name3 === 'TVA') ? 'VAT' : $item->tax_name3); } $invoiceLine = (new InvoiceLine()) ->setId($index + 1) ->setInvoicedQuantity($item->quantity) - ->setUnitCode($item->custom_value3) + ->setUnitCode($item->unit_code ?? 'C62') ->setLineExtensionAmount($item->line_total) ->setItem((new Item()) ->setName($item->product_key) ->setDescription($item->notes) - ->setClassifiedTaxCategory($classifiedTaxCategory)) + ->setClassifiedTaxCategory([$classifiedTaxCategory])) ->setPrice((new Price()) ->setPriceAmount($this->costWithDiscount($item))); @@ -365,6 +366,25 @@ class RoEInvoice extends AbstractService } } + private function resolveTaxCode($tax_id) + { + $code = $tax_id; + + match($tax_id){ + Product::PRODUCT_TYPE_REVERSE_TAX => $code = 'AE', // VAT_REVERSE_CHARGE = + Product::PRODUCT_TYPE_EXEMPT => $code = 'E', // EXEMPT_FROM_TAX = + Product::PRODUCT_TYPE_PHYSICAL => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_ZERO_RATED => $code = 'Z', // ZERO_RATED_GOODS = + Product::PRODUCT_TYPE_REDUCED_TAX => $code = 'AA', // LOWER_RATE = + Product::PRODUCT_TYPE_SERVICE => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_DIGITAL => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_SHIPPING => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_OVERRIDE_TAX => $code = 'S', // STANDARD_RATE = + }; + + return $code; + } + public function generateXml(): string { $ubl_invoice = $this->run(); // Call the existing handle method to get the UBLInvoice diff --git a/app/Services/Email/EmailDefaults.php b/app/Services/Email/EmailDefaults.php index 5346c0636fe6..19121cc12014 100644 --- a/app/Services/Email/EmailDefaults.php +++ b/app/Services/Email/EmailDefaults.php @@ -301,7 +301,7 @@ class EmailDefaults $documents = []; /* Return early if the user cannot attach documents */ - if (!$this->email->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT) || $this->email->email_object->email_template_subject == 'email_subject_statement') { + if (!$this->email->email_object->invitation || !$this->email->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT) || $this->email->email_object->email_template_subject == 'email_subject_statement') { return $this; }