order = $order; $this->lang = $lang; $this->type = $type; $this->currency = Currency::getCurrency()->dollar; } public function generate() { $tableData = $this->generateTableData(); $prepateData = $this->prepateData(); $product = $this->order->products()->get()->first()->product()->get()->first(); $category = $product->categories()->get()->first(); $template = $this->findTemplate($product); $templatePath = $template->full_path(); // if (!file_exists($templatePath)) { // throw new \Exception("Template file does not exist at path: " . $templatePath); // } $templateProcessor = new TemplateProcessor($templatePath); $templateProcessor->setValue('contract_number', $this->order->id); foreach ($prepateData as $key => $value) { try { $templateProcessor->setValue($key, $value); } catch (Exception $e) { Log::error($e); } } $calc = tempnam(sys_get_temp_dir(), "calc_time_" . time() . "jpg"); if ($product->calc) file_put_contents($calc, Storage::get($product->calc)); // Generate table data $templateProcessor->cloneRowAndSetValues('product_index', $tableData); // Set the total price $templateProcessor->setValue('product_total_price', number_format(ceiling($this->product_total_price * $this->currency, 100), 0, '.', ' ')); $templateProcessor->setValue('total_product_count', $this->total_product_count); $templateProcessor->setValue('product_tax_itself_total', number_format(ceiling($this->product_total_tax * $this->currency, 100), 0, '.', ' ')); $templateProcessor->setValue('product_price_with_tax_total', number_format($this->product_total_price_with_tax, 0, '.', ' ')); $templateProcessor->setValue('price_delivery_total', number_format($this->price_delivery_total, 0, ".", " ")); $templateProcessor->setValue('price_master_total', number_format($this->price_master_total, 0, ".", " ")); if ($product->calc) $templateProcessor->setImageValue("calc", ["path" => $calc, "width" => 700, "height" => 700]); else $templateProcessor->setValue("calc", ""); // Set seller info $templateProcessor->setValues($this->prepareSellerData()); // Create the directory if it does not exist if (!file_exists(storage_path('app/public/contracts'))) { mkdir(storage_path('app/public/contracts'), 0777, true); } // Define the file name and save path $fileName = 'contracts/contract_' . time() . '.docx'; $filePath = storage_path("app/public/{$fileName}"); // Save the new document $templateProcessor->saveAs($filePath); $this->storeImageToS3($fileName); return $fileName; } private function storeImageToS3($oldPath): void { // first store temp file and resize it, then upload to s3 // 1 - store temp file $path = storage_path('app/public/' . $oldPath); Storage::put($oldPath, file_get_contents($path)); // 3 - delete resized file if (is_file($path)) { unlink($path); } } private function findTemplate($product = null) { $is_getgreen = $product->categories()->where(['company' => "getgreen"])->exists(); $template = ContractTemplate::where('lang', $this->lang)->where('company', 'getgreen'); if ($this->type == 'physical') { $template = $template->where('type', 'physical')->latest()->first(); } elseif ($this->type == 'legal') { $template = $template->where('type', 'legal')->latest()->first(); } if (empty($template)) { throw new \Exception("Template not found"); } return $template; } private function prepareSellerData() { $seller = Company::latest()->first(); if (!$seller) { return []; } return [ 'seller_address' => $seller->address[$this->lang], 'seller_inn' => $seller->inn, 'seller_payment_account' => $seller->payment_account, 'seller_bank_name' => $seller->bank_name[$this->lang], 'seller_mfo' => $seller->mfo, 'seller_oked' => $seller->oked, 'seller_phone' => '+' . $seller->phone, 'seller_director_full_name' => $seller->director_full_name[$this->lang], ]; } private function prepateData() { // for legal user $date = Carbon::now(); $date->locale($this->lang); $data = [ 'date_day_in_num' => $date->day, 'date_month' => $date->translatedFormat('F'), 'date_year_in_num' => $date->year, ]; if ($this->type == 'legal') { $data['client_company_name'] = $this->order->legalInfo->company_name; $data['client_inn'] = $this->order->legalInfo->inn; $data['client_bank_name'] = $this->order->legalInfo->bank_name; $data['client_payment_account'] = $this->order->legalInfo->payment_account; $data['client_mfo'] = $this->order->legalInfo->mfo; $data['client_phone'] = '+' . $this->order->legalInfo->phone; $data['client_address'] = $this->order->legalInfo->address; $data['client_full_name'] = $this->order->legalInfo->director_full_name; return $data; } // For physical user $data['client_phone'] = '+' . $this->order->phone; $data['client_full_name'] = $this->order->full_name; $data['client_fish'] = $this->order->full_name; $data['client_address'] = $this->order->address()->get()->first()?->address; $data['clien_series'] = $this->order->series; $data['client_jshir'] = $this->order->jshir; return $data; } private function generateTableData() { $order = $this->order; $values = []; foreach ($order->products as $product) { $this->total_product_count += $product->count; $tax = $product->final_price / 112 * 12; $price_without_tax = $product->final_price - $tax; $this->product_total_price += $price_without_tax; $this->product_total_tax += $tax; $this->price_delivery_total += $order->price_delivery; $this->price_master_total += $order->price_master; $total = ceiling($product->final_price * $this->currency, 100) + $order->price_delivery + $order->price_master; $this->product_total_price_with_tax += $total; $values[] = [ 'measurement' => $product->product->measurement?->name[$this->lang], 'product_index' => count($values) + 1, 'product_name' => $product->product->name[$this->lang], 'product_price' => number_format(ceiling($price_without_tax * $this->currency, 100), 0, '.', ' '), 'product_count' => $product->count, 'product_tax_itself' => number_format(ceiling($tax * $this->currency, 100), 0, '.', ' '), 'product_price_with_tax' => number_format($total, 0, '.', ' '), "price_master" => number_format($order->price_master, 0, ".", " "), "price_delivery" => number_format($order->price_delivery, 0, ".", " ") ]; } return $values; } }