You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1956 lines
80 KiB
1956 lines
80 KiB
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use DateTime;
|
|
use Mpdf\Mpdf;
|
|
use App\Models\Brands;
|
|
use App\Models\Caisse;
|
|
use App\Models\Orders;
|
|
use App\Models\Stores;
|
|
use App\Models\Company;
|
|
use App\Models\Category;
|
|
use App\Models\Products;
|
|
use App\Models\Attributes;
|
|
use App\Models\OrderItems;
|
|
use App\Models\Remise;
|
|
|
|
use PhpParser\Node\Stmt\Else_;
|
|
|
|
class OrderController extends AdminController
|
|
{
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
private $pageTitle = 'Orders';
|
|
|
|
public function index()
|
|
{
|
|
$this->verifyRole('viewOrder');
|
|
$data['page_title'] = $this->pageTitle;
|
|
|
|
return $this->render_template('orders/index', $data);
|
|
}
|
|
|
|
public function fetchOrdersData()
|
|
{
|
|
// Load the required helpers
|
|
helper(['url', 'form']);
|
|
$Orders = new Orders();
|
|
$result = ['data' => []];
|
|
|
|
// Fetch orders data from the model
|
|
$data = $Orders->getOrdersData();
|
|
$session = session();
|
|
$users = $session->get('user');
|
|
if($users['group_name'] == "Caissière"){
|
|
foreach ($data as $key => $value) {
|
|
// $count_total_item = $Orders->countOrderItem($value['id']);
|
|
$date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); // Combine date and time formatting
|
|
|
|
// Initialize buttons
|
|
$buttons = '';
|
|
|
|
if (in_array('viewOrder', $this->permission)) {
|
|
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>';
|
|
}
|
|
|
|
if (in_array('viewOrder', $this->permission)) {
|
|
$buttons .= '
|
|
<a
|
|
href="#"
|
|
data-order-id="' . $value['id'] . '"
|
|
class="btn btn-default btn-view"
|
|
data-toggle="tooltip"
|
|
title="Voir">
|
|
<i class="fa fa-eye"></i>
|
|
</a>';
|
|
}
|
|
|
|
if (in_array('updateOrder', $this->permission) && $users["store_id"] == $value['store_id']) {
|
|
$buttons .= ' <a href="' . site_url('orders/update/' . $value['id']) . '" class="btn btn-primary"><i class="fa fa-pencil"></i></a>';
|
|
}
|
|
|
|
// Paid status label
|
|
$paid_status = ($value['paid_status'] == 1)
|
|
? '<span class="label label-success">Payé</span>'
|
|
: '<span class="label label-warning">Non payé</span>';
|
|
|
|
$date1 = new DateTime($date_time);
|
|
$date2 = new DateTime(); // Current date and time
|
|
|
|
// Calculate the difference in days
|
|
$interval = $date1->diff($date2);
|
|
$daysPassed = $interval->days;
|
|
|
|
$statuDate = '<span class="label label-success"></span>';
|
|
// die(var_dump($daysPassed));
|
|
$Notification = new NotificationController();
|
|
// die(var_dump($_SERVER['REQUEST_URI'] == "/orders/fetchOrdersData"));
|
|
$uri = $_SERVER['REQUEST_URI'];
|
|
if ($daysPassed < 8 && $value['paid_status'] == 2) {
|
|
$statuDate = '<span class="label label-success"> depuis ' . $daysPassed . ' Jours</span>';
|
|
} else if ($daysPassed >= 8 && $value['paid_status'] == 2) {
|
|
$Notification->createNotification("Conseil : Confirmation de reservation", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
|
|
$statuDate = '<span class="label label-warning"> depuis ' . $daysPassed . ' Jours</span>';
|
|
} else if ($daysPassed >= 15 && $value['paid_status'] == 2) {
|
|
$Notification->createNotification("Conseil : Reservation expiré", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
|
|
$statuDate = '<span class="label label-danger"> depuis ' . $daysPassed . ' Jours</span>';
|
|
}
|
|
$Orders_items= new OrderItems();
|
|
$sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
|
|
|
|
// Add data to the result array
|
|
$result['data'][$key] = [
|
|
$value['product_names'],
|
|
$value['user_name'],
|
|
$date_time . " <br >" . $statuDate,
|
|
$sum_order_item,
|
|
number_format((int) $value['net_amount'], 0, ',', ' '),
|
|
$paid_status,
|
|
$buttons
|
|
];
|
|
}
|
|
return $this->response->setJSON($result);
|
|
}
|
|
else if($users['group_name'] == "Direction" || $users['group_name'] == "Conseil"){
|
|
foreach ($data as $key => $value) {
|
|
// $count_total_item = $Orders->countOrderItem($value['id']);
|
|
$date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); // Combine date and time formatting
|
|
|
|
// Initialize buttons
|
|
$buttons = '';
|
|
|
|
if (in_array('viewOrder', $this->permission)) {
|
|
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>';
|
|
}
|
|
|
|
if (in_array('updateOrder', $this->permission)) {
|
|
$buttons .= ' <a href="' . site_url('orders/update/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-pencil"></i></a>';
|
|
}
|
|
|
|
if (in_array('deleteOrder', $this->permission)) {
|
|
$buttons .= ' <button type="button" class="btn btn-danger" onclick="removeFunc(' . $value['id'] . ')" data-toggle="modal" data-target="#removeModal"><i class="fa fa-trash"></i></button>';
|
|
}
|
|
|
|
// Paid status label
|
|
$paid_status = ($value['paid_status'] == 1)
|
|
? '<span class="label label-success">Payé</span>'
|
|
: '<span class="label label-warning">Non payé</span>';
|
|
|
|
$date1 = new DateTime($date_time);
|
|
$date2 = new DateTime(); // Current date and time
|
|
|
|
// Calculate the difference in days
|
|
$interval = $date1->diff($date2);
|
|
$daysPassed = $interval->days;
|
|
|
|
$statuDate = '<span class="label label-success"></span>';
|
|
// die(var_dump($daysPassed));
|
|
$Notification = new NotificationController();
|
|
// die(var_dump($_SERVER['REQUEST_URI'] == "/orders/fetchOrdersData"));
|
|
$uri = $_SERVER['REQUEST_URI'];
|
|
if ($daysPassed < 8 && $value['paid_status'] == 2) {
|
|
$statuDate = '<span class="label label-success"> depuis ' . $daysPassed . ' Jours</span>';
|
|
} else if ($daysPassed >= 8 && $value['paid_status'] == 2) {
|
|
$Notification->createNotification("Conseil : Confirmation de reservation", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
|
|
$statuDate = '<span class="label label-warning"> depuis ' . $daysPassed . ' Jours</span>';
|
|
} else if ($daysPassed >= 15 && $value['paid_status'] == 2) {
|
|
$Notification->createNotification("Conseil : Reservation expiré", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
|
|
$statuDate = '<span class="label label-danger"> depuis ' . $daysPassed . ' Jours</span>';
|
|
}
|
|
$Orders_items= new OrderItems();
|
|
$sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
|
|
|
|
// Add data to the result array
|
|
$result['data'][$key] = [
|
|
$value['bill_no'],
|
|
$value['customer_name'],
|
|
$value['customer_phone'],
|
|
$date_time . " <br >" . $statuDate,
|
|
$sum_order_item,
|
|
number_format((int) $value['net_amount'], 0, ',', ' '),
|
|
$paid_status,
|
|
$buttons
|
|
];
|
|
}
|
|
return $this->response->setJSON($result);
|
|
}
|
|
else {
|
|
if($users['group_name'] !== "Direction" || $users['group_name'] !== "Conseil"){
|
|
foreach ($data as $key => $value) {
|
|
|
|
// $count_total_item = $Orders->countOrderItem($value['id']);
|
|
$date_time = date('d-m-Y h:i a', strtotime($value['date_time'])); // Combine date and time formatting
|
|
|
|
// Initialize buttons
|
|
$buttons = '';
|
|
|
|
if (in_array('viewOrder', $this->permission)) {
|
|
$buttons .= '<a target="_blank" href="' . site_url('orders/printDiv/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-print"></i></a>';
|
|
}
|
|
|
|
if (in_array('updateOrder', $this->permission) && $users["id"] == $value['user_id']) {
|
|
$buttons .= ' <a href="' . site_url('orders/update/' . $value['id']) . '" class="btn btn-default"><i class="fa fa-pencil"></i></a>';
|
|
}
|
|
if (in_array('viewOrder', $this->permission)) {
|
|
$buttons .= '
|
|
<a
|
|
href="#"
|
|
data-order-id="' . $value['id'] . '"
|
|
class="btn btn-default btn-view"
|
|
data-toggle="tooltip"
|
|
title="Voir">
|
|
<i class="fa fa-eye"></i>
|
|
</a>';
|
|
}
|
|
|
|
|
|
if (in_array('deleteOrder', $this->permission) && $users["id"] == $value['user_id']) {
|
|
$buttons .= ' <button type="button" class="btn btn-danger" onclick="removeFunc(' . $value['id'] . ')" data-toggle="modal" data-target="#removeModal"><i class="fa fa-trash"></i></button>';
|
|
}
|
|
|
|
// Paid status label
|
|
$paid_status = ($value['paid_status'] == 1)
|
|
? '<span class="label label-success">Payé</span>'
|
|
: '<span class="label label-warning">Non payé</span>';
|
|
|
|
$date1 = new DateTime($date_time);
|
|
$date2 = new DateTime(); // Current date and time
|
|
|
|
// Calculate the difference in days
|
|
$interval = $date1->diff($date2);
|
|
$daysPassed = $interval->days;
|
|
|
|
$statuDate = '<span class="label label-success"></span>';
|
|
// die(var_dump($daysPassed));
|
|
$Notification = new NotificationController();
|
|
// die(var_dump($_SERVER['REQUEST_URI'] == "/orders/fetchOrdersData"));
|
|
$uri = $_SERVER['REQUEST_URI'];
|
|
if ($daysPassed < 8 && $value['paid_status'] == 2) {
|
|
$statuDate = '<span class="label label-success"> depuis ' . $daysPassed . ' Jours</span>';
|
|
} else if ($daysPassed >= 8 && $value['paid_status'] == 2) {
|
|
$Notification->createNotification("Conseil : Confirmation de reservation", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
|
|
$statuDate = '<span class="label label-warning"> depuis ' . $daysPassed . ' Jours</span>';
|
|
} else if ($daysPassed >= 15 && $value['paid_status'] == 2) {
|
|
$Notification->createNotification("Conseil : Reservation expiré", "TOUS", (int)$value['store_id'], str_contains($uri, "fetchOrdersData") ? 'orders/#' : 'orders');
|
|
$statuDate = '<span class="label label-danger"> depuis ' . $daysPassed . ' Jours</span>';
|
|
}
|
|
$Orders_items= new OrderItems();
|
|
$sum_order_item = $Orders_items->getSumOrdersItemData($value['id']);
|
|
|
|
// Add data to the result array
|
|
$result['data'][$key] = [
|
|
$value['product_names'],
|
|
$value['user_name'],
|
|
$date_time . " <br >" . $statuDate,
|
|
$sum_order_item,
|
|
number_format((int) $value['net_amount'], 0, ',', ' '),
|
|
$paid_status,
|
|
$buttons
|
|
];
|
|
}
|
|
return $this->response->setJSON($result);
|
|
}
|
|
}
|
|
// Return JSON response
|
|
|
|
}
|
|
|
|
/**
|
|
* function who check if the product is null
|
|
* and create notification about it
|
|
* @param array $product_id id of the product
|
|
* @param int $store_id id of the store
|
|
* @return void
|
|
*/
|
|
private function checkProductisNull(array $product_id, $store_id)
|
|
{
|
|
$notification = new NotificationController();
|
|
$product = new Products();
|
|
for ($i = 0; $i < count($product_id); $i++) {
|
|
$singleProduct = $product->getProductData($product_id[$i]);
|
|
if ($singleProduct['product_sold'] == true) {
|
|
$notification->createNotification("Produit en rupture de stock", "Conseil", $store_id, "products");
|
|
}
|
|
}
|
|
}
|
|
|
|
private function calculGross($request)
|
|
{
|
|
$amount = $request;
|
|
$montant = 0;
|
|
for ($i = 0; $i < \count($amount); $i++) {
|
|
$montant += $amount[$i];
|
|
}
|
|
|
|
return $montant;
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
$this->verifyRole('createOrder');
|
|
$data['page_title'] = $this->pageTitle;
|
|
|
|
// Load validation service
|
|
$validation = \Config\Services::validation();
|
|
|
|
// echo '<pre>';
|
|
// die(var_dump($this->request->getPost('product[]')));
|
|
|
|
$products = $this->request->getPost('product[]');
|
|
|
|
// Then, manually check for uniqueness
|
|
if ($products !== null && (count($products) !== count(array_unique($products)))) {
|
|
return redirect()->back()->withInput()->with('errors', ['product' => 'Chaque produit sélectionné doit être unique.']);
|
|
}
|
|
|
|
// Set validation rules
|
|
$validation->setRules([
|
|
'product[]' => 'required'
|
|
]);
|
|
// echo '<pre>';
|
|
// die(var_dump($this->request->getPost()));
|
|
|
|
$validationData = [
|
|
'product[]' => $this->request->getPost('product[]')
|
|
];
|
|
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
|
|
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
|
|
|
|
$session = session();
|
|
$users = $session->get('user');
|
|
$user_id = $users['id'];
|
|
$bill_no = 'BILPR-' . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 4));
|
|
|
|
// If validation passes
|
|
|
|
$data = [
|
|
'bill_no' => $bill_no,
|
|
'customer_name' => $this->request->getPost('customer_name'),
|
|
'customer_address' => $this->request->getPost('customer_address'),
|
|
'customer_phone' => $this->request->getPost('customer_phone'),
|
|
'customer_cin' => $this->request->getPost('customer_cin'),
|
|
'date_time' => date('Y-m-d H:i:s'),
|
|
'service_charge_rate' => $this->request->getPost('service_charge_rate'),
|
|
'vat_charge_rate' => $this->request->getPost('vat_charge_rate'),
|
|
'vat_charge' => ($this->request->getPost('vat_charge_value') > 0) ? $this->request->getPost('vat_charge_value') : 0,
|
|
'net_amount' => $this->request->getPost('net_amount'),
|
|
'discount' => $this->request->getPost('discount'),
|
|
'paid_status' => 2,
|
|
'user_id' => $user_id,
|
|
// 'qty' => $this->request->getPost('qty[]'),
|
|
'amount_value' => $this->request->getPost('amount_value[]'),
|
|
'gross_amount' => $this->calculGross($this->request->getPost('amount_value[]')),
|
|
'rate_value' => $this->request->getPost('rate_value[]'),
|
|
'store_id' => $users['store_id'],
|
|
];
|
|
|
|
$posts = $this->request->getPost('product[]');
|
|
|
|
// echo '<pre>';
|
|
// die(var_dump($data));
|
|
$order_id = $Orders->create($data, $posts);
|
|
$Order_item1 = new OrderItems();
|
|
$order_item_data = $Order_item1->getOrdersItemData($order_id);
|
|
$product_ids = array_column($order_item_data, 'product_id');
|
|
|
|
$Notification = new NotificationController();
|
|
|
|
if ((int) (int) $this->request->getPost('discount') > 0) {
|
|
$productData = new Products();
|
|
$product_data_results = [];
|
|
|
|
foreach ($product_ids as $prod_id) {
|
|
|
|
$id = (int) $prod_id;
|
|
|
|
// Appel de la méthode pour chaque ID
|
|
$product_data_results[] = $productData->getProductData($id);
|
|
}
|
|
|
|
$product_lines = [];
|
|
|
|
foreach ($product_data_results as $product) {
|
|
if (isset($product['sku'], $product['price'])) {
|
|
$sku = $product['sku'];
|
|
$price = $product['price'];
|
|
$product_lines[] = "{$sku}:{$price}";
|
|
}
|
|
}
|
|
|
|
$product_output = implode("\n", $product_lines);
|
|
|
|
|
|
// data for the remise
|
|
$data1 = [
|
|
'date_demande' => date('Y-m-d H:i:s'),
|
|
'montant_demande' => $this->request->getPost('discount'),
|
|
'total_price' => $this->request->getPost('amount_value[]'),
|
|
'id_store' => $users['store_id'],
|
|
'id_order' => $order_id,
|
|
'product' => $product_output,
|
|
'demande_status' => 'En attente'
|
|
];
|
|
|
|
$Remise = new Remise();
|
|
$id_remise = $Remise->addDemande($data1);
|
|
$Notification->createNotification("Un nouveau demande de remise été ajouté", "Conseil", (int)$users['store_id'], 'remise');
|
|
}
|
|
|
|
if ($order_id) {
|
|
session()->setFlashdata('success', 'Créé avec succès');
|
|
$Notification->createNotification("Un nouveau commade ajouter", "Caissière", (int)$users['store_id'], "orders");
|
|
if ($users["group_name"] != "COMMERCIALE") {
|
|
|
|
$this->checkProductisNull($posts, $users['store_id']);
|
|
|
|
return redirect()->to('orders/update/' . $order_id);
|
|
} else {
|
|
|
|
return redirect()->to('orders/');
|
|
}
|
|
} else {
|
|
session()->setFlashdata('errors', 'Error occurred!!');
|
|
return redirect()->to('orders/create/');
|
|
}
|
|
} else {
|
|
// If validation fails
|
|
$company = $Company->getCompanyData(1);
|
|
|
|
$session = session();
|
|
$users = $session->get('user');
|
|
$store_id = $users['store_id'];
|
|
// Prepare data for the view
|
|
$data = [
|
|
'company_data' => $company,
|
|
'is_vat_enabled' => ($company['vat_charge_value'] > 0),
|
|
'is_service_enabled' => ($company['service_charge_value'] > 0),
|
|
'products' => $Products->getProductData2($store_id),
|
|
'validation' => $validation,
|
|
'page_title' => $this->pageTitle,
|
|
];
|
|
|
|
// Render the view with the prepared data
|
|
return $this->render_template('orders/create', $data);
|
|
}
|
|
}
|
|
|
|
public function getProductValueById()
|
|
{
|
|
$product_id = $this->request->getPost('product_id');
|
|
if ($product_id) {
|
|
$Products = new Products();
|
|
$product_data = $Products->getProductData($product_id);
|
|
return $this->response->setJSON($product_data);
|
|
}
|
|
}
|
|
|
|
public function getTableProductRow()
|
|
{
|
|
$Products = new Products();
|
|
$session = session();
|
|
$users = $session->get('user');
|
|
$store_id = $users['store_id'];
|
|
|
|
$product_data = $Products->getProductData2($store_id);
|
|
die(var_dump($product_data));
|
|
return $this->response->setJSON($product_data);
|
|
}
|
|
|
|
|
|
public function update(int $id)
|
|
{
|
|
$this->verifyRole('updateOrder');
|
|
|
|
$data['page_title'] = $this->pageTitle;
|
|
$validation = \Config\Services::validation();
|
|
|
|
// Définir les règles de validation
|
|
$validation->setRules([
|
|
'product' => 'required'
|
|
]);
|
|
|
|
$validationData = [
|
|
'product' => $this->request->getPost('product')
|
|
];
|
|
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
$OrderItems = new OrderItems();
|
|
|
|
if ($this->request->getMethod() === 'post' && $validation->run($validationData)) {
|
|
$dataUpdate = [
|
|
'customer_name' => $this->request->getPost('customer_name'),
|
|
'customer_address' => $this->request->getPost('customer_address'),
|
|
'customer_phone' => $this->request->getPost('customer_phone'),
|
|
'customer_cin' => $this->request->getPost('customer_cin'),
|
|
'gross_amount' => $this->request->getPost('gross_amount_value'),
|
|
'service_charge_rate' => $this->request->getPost('service_charge_rate'),
|
|
'service_charge' => max(0, (float)$this->request->getPost('service_charge_value')),
|
|
'vat_charge_rate' => $this->request->getPost('vat_charge_rate'),
|
|
'vat_charge' => max(0, (float)$this->request->getPost('vat_charge_value')),
|
|
'net_amount' => $this->request->getPost('net_amount_value'),
|
|
'discount' => $this->request->getPost('discount'),
|
|
'paid_status' => $this->request->getPost('paid_status'),
|
|
'product' => $this->request->getPost('product'),
|
|
'product_sold' => true,
|
|
'rate_value' => $this->request->getPost('rate_value'),
|
|
'amount_value' => $this->request->getPost('amount_value'),
|
|
'tranche_1' => $this->request->getPost('tranche_1'),
|
|
'tranche_2' => $this->request->getPost('tranche_2'),
|
|
'order_payment_mode' => $this->request->getPost('order_payment_mode_1'),
|
|
'order_payment_mode_1' => $this->request->getPost('order_payment_mode_2')
|
|
];
|
|
|
|
if ($Orders->updates($id, $dataUpdate)) {
|
|
$order_item_data = $OrderItems->getOrdersItemData($id);
|
|
$product_ids = array_column($order_item_data, 'product_id');
|
|
|
|
$Notification = new NotificationController();
|
|
|
|
$discount = (int) $this->request->getPost('discount');
|
|
|
|
if ($discount > 0) {
|
|
$productData = new Products();
|
|
$product_data_results = [];
|
|
|
|
foreach ($product_ids as $product_id) {
|
|
$product_data_results[] = $productData->getProductData((int) $product_id);
|
|
}
|
|
|
|
$product_lines = [];
|
|
foreach ($product_data_results as $product) {
|
|
if (isset($product['sku'], $product['price'])) {
|
|
$product_lines[] = "{$product['sku']}:{$product['price']}";
|
|
}
|
|
}
|
|
|
|
$product_output = implode("\n", $product_lines);
|
|
|
|
$session = session();
|
|
$users = $session->get('user');
|
|
|
|
$data1 = [
|
|
'date_demande' => date('Y-m-d H:i:s'),
|
|
'montant_demande' => $this->request->getPost('discount'),
|
|
'total_price' => $this->request->getPost('amount_value'),
|
|
'id_store' => $users['store_id'],
|
|
'id_order' => $id,
|
|
'product' => $product_output,
|
|
'demande_status' => 'En attente'
|
|
];
|
|
|
|
$Remise = new Remise();
|
|
$Remise->updateRemise1($id,$data1);
|
|
$Notification->createNotification("Un nouveau demande de remise a été ajouté", "Conseil", (int)$users['store_id'] ?? null, 'remise');
|
|
}
|
|
|
|
session()->setFlashData('success', 'Commande mise à jour avec succès.');
|
|
return redirect()->to('orders/update/' . $id);
|
|
} else {
|
|
session()->setFlashData('errors', 'Une erreur est survenue lors de la mise à jour.');
|
|
return redirect()->to('orders/update/' . $id);
|
|
}
|
|
}
|
|
|
|
// En cas d’échec de la validation ou si GET
|
|
$company = $Company->getCompanyData(1);
|
|
$data['company_data'] = $company;
|
|
$data['is_vat_enabled'] = ($company['vat_charge_value'] > 0);
|
|
$data['is_service_enabled'] = ($company['service_charge_value'] > 0);
|
|
|
|
$orders_data = $Orders->getOrdersData($id);
|
|
$result = ['order' => $orders_data];
|
|
$orders_item = $OrderItems->getOrdersItemData($orders_data['id']);
|
|
|
|
foreach ($orders_item as $item) {
|
|
$result['order_item'][] = $item;
|
|
}
|
|
|
|
$data['order_data'] = $result;
|
|
$data['products'] = $Products->getActiveProductData();
|
|
$data['validation'] = $validation;
|
|
|
|
return $this->render_template('orders/edit', $data);
|
|
}
|
|
|
|
|
|
|
|
public function lookOrder(int $id)
|
|
{
|
|
$this->verifyRole('viewOrder');
|
|
|
|
$data['page_title'] = $this->pageTitle;
|
|
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
$OrderItems = new OrderItems();
|
|
|
|
// En cas d’échec de la validation ou si GET
|
|
$company = $Company->getCompanyData(1);
|
|
$data['company_data'] = $company;
|
|
$data['is_vat_enabled'] = ($company['vat_charge_value'] > 0);
|
|
$data['is_service_enabled'] = ($company['service_charge_value'] > 0);
|
|
|
|
$orders_data = $Orders->getOrdersData($id);
|
|
$sum_order_item = $OrderItems->getSumOrdersItemData($orders_data['id']);
|
|
$result = [
|
|
'order' => $orders_data,
|
|
'sum_order_data' => $sum_order_item
|
|
];
|
|
|
|
$orders_item = $OrderItems->getOrdersItemData($orders_data['id']);
|
|
|
|
foreach ($orders_item as $item) {
|
|
$result['order_item'][] = $item;
|
|
}
|
|
|
|
$data['order_data'] = $result;
|
|
$data['products'] = $Products->getActiveProductData();
|
|
|
|
return $this->response->setJSON($data);
|
|
|
|
}
|
|
|
|
/**
|
|
* return storename
|
|
* @param int $id
|
|
* @return string
|
|
*/
|
|
private function returnStore($id)
|
|
{
|
|
$Stores = new Stores();
|
|
$store = $Stores->getActiveStore();
|
|
$name = "";
|
|
|
|
foreach ($store as $key => $value) {
|
|
if ($value['id'] == $id) {
|
|
$name = $value['name'];
|
|
}
|
|
}
|
|
|
|
return $name;
|
|
}
|
|
|
|
public function print2(int $id)
|
|
{
|
|
$this->verifyRole('viewOrder');
|
|
|
|
if ($id) {
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
$OrderItems = new OrderItems();
|
|
|
|
// Récupération des données
|
|
$order_data = $Orders->getOrdersData($id);
|
|
$orders_items = $OrderItems->getOrdersItemData($id);
|
|
$company_info = $Company->getCompanyData(1);
|
|
// die(\var_dump($orders_items));
|
|
|
|
$html = '';
|
|
// Vérifier si l'utilisateur a payé
|
|
$paid_status = ($order_data['paid_status'] == 1) ? "<span style='color: green; font-weight: bold;'>Payé</span>" : "<span style='color: red; font-weight: bold;'>Non payé</span>";
|
|
|
|
// Génération du HTML
|
|
$html .= '<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">
|
|
<style>
|
|
body { font-size: 14px; font-family: Arial, sans-serif; }
|
|
.invoice-container {
|
|
max-width: 750px; /* Réduire la largeur du cadre */
|
|
margin: 20px auto;
|
|
padding: 20px;
|
|
border: 2px solid #007bff; /* Bordure plus visible */
|
|
border-radius: 10px;
|
|
background: #f0f8ff; /* Couleur de fond plus douce */
|
|
}
|
|
.invoice-header {
|
|
background: #007bff;
|
|
color: white;
|
|
text-align: center;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
padding: 10px;
|
|
border-radius: 10px 10px 0 0;
|
|
}
|
|
.invoice-footer {
|
|
background: #007bff;
|
|
color: white;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
padding: 10px;
|
|
border-radius: 0 0 10px 10px;
|
|
margin-top: 12px;
|
|
}
|
|
table { width: 100%; border-collapse: collapse; }
|
|
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
|
|
th { background: #e9ecef; }
|
|
p, strong { color: #333; }
|
|
@media print {
|
|
body { font-size: 14px; font-family: Arial, sans-serif, margin: 1cm; }
|
|
|
|
@page { margin: 0; }
|
|
|
|
.invoice-container {
|
|
max-width: 750px;
|
|
margin: 20px auto;
|
|
padding: 20px;
|
|
border: 2px solid #007bff;
|
|
border-radius: 10px;
|
|
background: #f0f8ff;
|
|
}
|
|
|
|
.invoice-header {
|
|
background: #007bff !important;
|
|
color: white !important;
|
|
text-align: center;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
padding: 10px;
|
|
border-radius: 10px 10px 0 0;
|
|
}
|
|
|
|
input {
|
|
border: none;
|
|
outline: none;
|
|
width: 100%;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.invoice-footer {
|
|
background: #007bff !important;
|
|
color: white !important;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
padding: 10px;
|
|
border-radius: 0 0 10px 10px;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
table { width: 100%; border-collapse: collapse; }
|
|
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
|
|
th { background: #e9ecef; }
|
|
p, strong { color: #333; } a
|
|
|
|
/* Supprimer l\'ombre et les bordures non nécessaires */
|
|
.invoice-container { box-shadow: none !important; border: none !important; }
|
|
|
|
/* Éviter que les couleurs soient supprimées à l\'impression */
|
|
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body onload="window.print();">
|
|
<div class="invoice-container">
|
|
<div class="invoice-header" style="background: #007bff;color: white;text-align: center;font-size: 18px;font-weight: bold;padding: 10px;border-radius: 10px 10px 0 0; ">
|
|
' . esc($company_info['company_name']) . '
|
|
</div>
|
|
<div style="display: flex;justify-content: space-around;margin-top: 3%;">
|
|
<div>
|
|
<p><strong>Facture ID :</strong> ' . esc($order_data['bill_no']) . '</p>
|
|
<p><strong>NIF :</strong> ' . esc($company_info['NIF']) . '</p>
|
|
<p><strong>STAT :</strong> ' . esc($company_info['STAT']) . '</p>
|
|
<p style="display: flex; gap: 10px;">
|
|
<strong>Contact :</strong>
|
|
<span>' . esc($company_info['phone']) . '</span>
|
|
<span>' . esc($company_info['phone2']) . '</span>
|
|
</p>
|
|
<p><strong>Magasin :</strong> ' . esc($this->returnStore($order_data['store_id'])) . '</p>
|
|
</div>
|
|
<div>
|
|
<p><strong>Nom:</strong> ' . esc($order_data['customer_name']) . '</p>
|
|
<p><strong>Adresse:</strong> ' . esc($order_data['customer_address']) . '</p>
|
|
<p><strong>Téléphone:</strong> ' . esc($order_data['customer_phone']) . '</p>
|
|
<p><strong>CIN:</strong> ' . esc($order_data['customer_cin']) . '</p>
|
|
<br >
|
|
<br >
|
|
<p><strong>Antananarivo le</strong> ' . esc(date('d/m/Y')) . '</p>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Marque</th>
|
|
<th>Moteur</th>
|
|
<th>Puissance</th>
|
|
<th>Prix</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
|
|
foreach ($orders_items as $item) {
|
|
$product_data = $Products->getProductData($item['product_id']);
|
|
$html .= '<tr>
|
|
<td>' . esc($product_data['sku']) . '</td>
|
|
<td>' . esc($product_data['numero_de_moteur']) . '</td>
|
|
<td><input type="text" name="customField" placeholder="Remplir ici" style="border: none; outline: none; width: 100%;" value="' . esc($product_data['puissance']) . '"></td>
|
|
<td style="text-align:right;">' . number_format((float) $item['amount'], 2, '.', ' ') . '</td>
|
|
</tr>';
|
|
}
|
|
|
|
$html .= ' </tbody>
|
|
</table>
|
|
<table class="table">
|
|
<tr>
|
|
<th>Total:</th>
|
|
<td>' . number_format(((float) $order_data['gross_amount'] - ((float) $order_data['gross_amount'] * 0.2)), 2, '.', ' ') . '</td>
|
|
</tr>
|
|
<tr>
|
|
<th>TVA:</th>
|
|
<td>' . number_format((((float) $order_data['gross_amount'] * 0.2)), 2, '.', ' ') . '</td>
|
|
</tr>';
|
|
|
|
$html .= '<tr>
|
|
<th>Réduction:</th>
|
|
<td>' . number_format((float) $order_data['discount'], 2, '.', ' ') . '</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Total à payer:</th>
|
|
<td><strong>' . number_format((float) ($order_data['net_amount']), 2, '.', ' ') . '</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<th>Statut:</th>
|
|
<td>' . $paid_status . '</td>
|
|
</tr>';
|
|
|
|
// Vérification et ajout des informations de paiement
|
|
if (!empty($order_data['order_payment_mode'])) {
|
|
$html .= '<tr>
|
|
<th>Mode de paiement:</th>
|
|
<td><strong>' . esc($order_data['order_payment_mode']) . '</strong></td>
|
|
</tr>';
|
|
}
|
|
|
|
if (!empty($order_data['tranche_1'])) {
|
|
$html .= '<tr>
|
|
<th>Tranche 1:</th>
|
|
<td><strong>' . number_format((float) $order_data['tranche_1'], 2, '.', ' ') . '</strong></td>
|
|
</tr>';
|
|
}
|
|
|
|
if (!empty($order_data['tranche_2'])) {
|
|
$html .= '<tr>
|
|
<th>Tranche 2:</th>
|
|
<td><strong>' . number_format((float) $order_data['tranche_2'], 2, '.', ' ') . '</strong></td>
|
|
</tr>';
|
|
}
|
|
|
|
$html .= '</table>
|
|
<div style="display: flex;align-items: center;justify-content: space-around;margin-bottom: 5%;">
|
|
<div>
|
|
<p style="font-weight:bold;">L\'acheteur</p>
|
|
</div>
|
|
<div>
|
|
<p style="font-weight:bold;">Le vendeur</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="invoice-footer">
|
|
Merci pour votre achat !<br>
|
|
<strong style="color:white;">Original</strong>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>';
|
|
return $this->response->setBody($html);
|
|
}
|
|
}
|
|
|
|
public function print(int $id)
|
|
{
|
|
$this->verifyRole('viewOrder');
|
|
|
|
if ($id) {
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
$OrderItems = new OrderItems();
|
|
|
|
$order_data = $Orders->getOrdersData($id);
|
|
$orders_items = $OrderItems->getOrdersItemData($id);
|
|
$company_info = $Company->getCompanyData(1);
|
|
|
|
$paid_status = ($order_data['paid_status'] == 1)
|
|
? "<span style='color: green; font-weight: bold;'>Payé</span>"
|
|
: "<span style='color: red; font-weight: bold;'>Non payé</span>";
|
|
|
|
foreach ($orders_items as $index => $item) {
|
|
$product_data = $Products->getProductData($item['product_id']);
|
|
|
|
echo '<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">
|
|
<style>
|
|
body { font-size: 14px; font-family: Arial, sans-serif; margin: 0; padding: 0; }
|
|
.invoice-container {
|
|
max-width: 750px;
|
|
margin: 20px auto;
|
|
padding: 20px;
|
|
border: 2px solid #007bff;
|
|
border-radius: 10px;
|
|
background: #f0f8ff;
|
|
page-break-after: always;
|
|
}
|
|
.invoice-header {
|
|
background: #007bff !important;
|
|
color: white;
|
|
text-align: center;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
padding: 10px;
|
|
border-radius: 10px 10px 0 0;
|
|
}
|
|
.invoice-footer {
|
|
background: #007bff !important;
|
|
color: white;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
padding: 10px;
|
|
border-radius: 0 0 10px 10px;
|
|
margin-top: 12px;
|
|
}
|
|
table { width: 100%; border-collapse: collapse; }
|
|
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
|
|
th { background: #e9ecef; }
|
|
input {
|
|
border: none;
|
|
outline: none;
|
|
width: 100%;
|
|
font-size: 14px;
|
|
}
|
|
@media print {
|
|
body { font-size: 14px; font-family: Arial, sans-serif, margin: 1cm; }
|
|
|
|
@page { margin: 0; }
|
|
* { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
|
|
body, .invoice-container {
|
|
margin: 0;
|
|
padding: 0;
|
|
border: none;
|
|
box-shadow: none;
|
|
}
|
|
.invoice-container {
|
|
page-break-after: always;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body onload="window.print()">
|
|
<div class="invoice-container">
|
|
<div class="invoice-header">' . esc($company_info['company_name']) . '</div>
|
|
|
|
<div style="display: flex; justify-content: space-around; margin-top: 3%;">
|
|
<div>
|
|
<p><strong>Facture ID :</strong> ' . esc($order_data['bill_no']) . '</p>
|
|
<p><strong>NIF :</strong> ' . esc($company_info['NIF']) . '</p>
|
|
<p><strong>STAT :</strong> ' . esc($company_info['STAT']) . '</p>
|
|
<p style="display: flex; gap: 10px;">
|
|
<strong>Contact :</strong>
|
|
<span>' . esc($company_info['phone']) . '</span>
|
|
<span>' . esc($company_info['phone2']) . '</span>
|
|
</p>
|
|
<p><strong>Magasin :</strong> ' . esc($this->returnStore($order_data['store_id'])) . '</p>
|
|
</div>
|
|
<div>
|
|
<p><strong>Nom:</strong> ' . esc($order_data['customer_name']) . '</p>
|
|
<p><strong>Adresse:</strong> ' . esc($order_data['customer_address']) . '</p>
|
|
<p><strong>Téléphone:</strong> ' . esc($order_data['customer_phone']) . '</p>
|
|
<p><strong>CIN:</strong> ' . esc($order_data['customer_cin']) . '</p>
|
|
<br><br>
|
|
<p><strong>Antananarivo le</strong> ' . esc(date('d/m/Y')) . '</p>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>Marque</th>
|
|
<th>Moteur</th>
|
|
<th>Puissance</th>
|
|
<th>Prix</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>' . esc($product_data['sku']) . '</td>
|
|
<td>' . esc($product_data['numero_de_moteur']) . '</td>
|
|
<td><input type="text" value="' . esc($product_data['puissance']) . '" placeholder="Remplir ici"></td>
|
|
<td style="text-align:right;">' . number_format((float)$item['amount'], 2, '.', ' ') . '</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<table class="table">
|
|
<tr>
|
|
<th>Total:</th>
|
|
<td>' . number_format($item['amount'] - ($item['amount'] * 0.2), 2, '.', ' ') . '</td>
|
|
</tr>
|
|
<tr>
|
|
<th>TVA:</th>
|
|
<td>' . number_format($item['amount'] * 0.2, 2, '.', ' ') . '</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Réduction:</th>
|
|
<td>' . number_format($order_data['discount'], 2, '.', ' ') . '</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Total à payer:</th>
|
|
<td><strong>' . number_format($item['amount'] - $order_data['discount'], 2, '.', ' ') . '</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<th>Statut:</th>
|
|
<td>' . $paid_status . '</td>
|
|
</tr>';
|
|
|
|
if (!empty($order_data['order_payment_mode'])) {
|
|
echo '<tr><th>Mode de paiement:</th><td><strong>' . esc($order_data['order_payment_mode']) . '</strong></td></tr>';
|
|
}
|
|
|
|
if (!empty($order_data['tranche_1'])) {
|
|
echo '<tr><th>Tranche 1:</th><td><strong>' . number_format((float)$order_data['tranche_1'], 2, '.', ' ') . '</strong></td></tr>';
|
|
}
|
|
|
|
if (!empty($order_data['tranche_2'])) {
|
|
echo '<tr><th>Tranche 2:</th><td><strong>' . number_format((float)$order_data['tranche_2'], 2, '.', ' ') . '</strong></td></tr>';
|
|
}
|
|
|
|
echo '</table>
|
|
|
|
<div style="display: flex; justify-content: space-around; margin-top: 5%;">
|
|
<div><p style="font-weight:bold;">L\'acheteur</p></div>
|
|
<div><p style="font-weight:bold;">Le vendeur</p></div>
|
|
</div>
|
|
|
|
<div class="invoice-footer">
|
|
Merci pour votre achat !<br>
|
|
<strong style="color:white;">Original</strong>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>';
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public function remove()
|
|
{
|
|
$this->verifyRole('deleteOrder');
|
|
$order_id = $this->request->getPost('order_id');
|
|
$response = [];
|
|
|
|
if ($order_id) {
|
|
$Orders = new Orders();
|
|
if ($Orders->remove($order_id)) {
|
|
|
|
$response['success'] = true;
|
|
$response['messages'] = "Successfully removed";
|
|
} else {
|
|
$response['success'] = false;
|
|
$response['messages'] = "Error in the database while removing the product information";
|
|
}
|
|
} else {
|
|
$response['success'] = false;
|
|
$response['messages'] = "Refersh the page again!!";
|
|
}
|
|
return $this->response->setJSON($response);
|
|
}
|
|
|
|
public function createById(int $id)
|
|
{
|
|
$this->verifyRole('createOrder');
|
|
$data['page_title'] = $this->pageTitle;
|
|
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
|
|
// If validation fails
|
|
$company = $Company->getCompanyData(1);
|
|
|
|
// Prepare data for the view
|
|
$data = [
|
|
'company_data' => $company,
|
|
'is_vat_enabled' => ($company['vat_charge_value'] > 0),
|
|
'is_service_enabled' => ($company['service_charge_value'] > 0),
|
|
'products' => $Products->getProductData($id),
|
|
'totalqtt' => $Products->getProductData($id)['qty'],
|
|
'pu' => $Products->getProductData($id)['prix_vente'],
|
|
'page_title' => $this->pageTitle,
|
|
];
|
|
|
|
return $this->render_template('orders/createbyid', $data);
|
|
}
|
|
|
|
// update caisse
|
|
public function update_caisse($data)
|
|
{
|
|
$p1 = 0;
|
|
$p2 = 0;
|
|
$op = "";
|
|
$p3 = 0;
|
|
$dest = "";
|
|
if ($data['tranche2']) {
|
|
if ($data['order']) {
|
|
# code...
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public function print3(int $id)
|
|
{
|
|
// Vérification du rôle
|
|
$this->verifyRole('viewOrder');
|
|
|
|
if (!$id) {
|
|
return $this->response->setStatusCode(400, 'ID manquant');
|
|
}
|
|
|
|
// Instanciation des modèles
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$OrderItems = new OrderItems();
|
|
$Products = new Products();
|
|
|
|
// Récupération des données
|
|
$order_data = $Orders->getOrdersData($id);
|
|
$items = $OrderItems->getOrdersItemData($id);
|
|
$company_info = $Company->getCompanyData(1);
|
|
|
|
// Statut de paiement
|
|
$paid_status = $order_data['paid_status'] == 1
|
|
? "<span style='color: green; font-weight: bold;'>Payé</span>"
|
|
: "<span style='color: red; font-weight: bold;'>Non payé</span>";
|
|
|
|
// STYLE COMMUN
|
|
$style = '
|
|
<style>
|
|
body { font-family: Arial, sans-serif; font-size:14px; margin:0; padding:0; }
|
|
.invoice-container { max-width:750px; margin:20px auto; padding:20px;
|
|
border:2px solid #007bff; border-radius:10px; page-break-after:always; }
|
|
.invoice-header { background:#007bff !important; color:#fff; text-align:center;
|
|
font-size:18px; padding:10px; border-radius:10px 10px 0 0; }
|
|
.invoice-footer { background:#007bff !important; color:#fff; text-align:center;
|
|
font-size:14px; padding:10px; border-radius:0 0 10px 10px; margin-top:12px; }
|
|
.info { display:flex; justify-content:space-between; margin-top:15px; }
|
|
table { width:100%; border-collapse:collapse; margin-top:15px; }
|
|
th, td { border:1px solid #ddd; padding:8px; text-align:left; }
|
|
th { background:#e9ecef; }
|
|
.summary {
|
|
width: 80%;
|
|
margin: 20px 0;
|
|
margin-right: 0;
|
|
}
|
|
.summary th, .summary td { border:none; padding:4px; text-align:right; }
|
|
.summary th { text-align:left; }
|
|
@media print {
|
|
body { font-size: 14px; font-family: Arial, sans-serif, margin: 1cm; }
|
|
|
|
@page { margin: 0; }
|
|
* { -webkit-print-color-adjust:exact; print-color-adjust:exact; } }
|
|
</style>
|
|
';
|
|
|
|
// --- FACTURES : Une par produit ---
|
|
foreach ($items as $item) {
|
|
$product_data = $Products->getProductData($item['product_id']);
|
|
$unitPrice = (float)$item['amount'];
|
|
$quantity = isset($item['qty']) ? (int)$item['qty'] : 1;
|
|
$subtotal = $unitPrice * $quantity;
|
|
$vatAmount = $subtotal * 0.2;
|
|
$discount = (float)$order_data['discount'];
|
|
$totalNet = $subtotal + $vatAmount - $discount;
|
|
|
|
echo '<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">
|
|
' . $style . '
|
|
</head>
|
|
<body onload="window.print()">
|
|
<div class="invoice-container">
|
|
<div class="invoice-header">FACTURE</div>
|
|
<div class="info">
|
|
<div>
|
|
<p><strong>Facture ID :</strong> ' . esc($order_data['bill_no']) . '</p>
|
|
<p><strong>NIF :</strong> ' . esc($company_info['NIF']) . '</p>
|
|
<p><strong>STAT :</strong> ' . esc($company_info['STAT']) . '</p>
|
|
<p><strong>Contact :</strong> ' . esc($company_info['phone']) . ' / ' . esc($company_info['phone2']) . '</p>
|
|
<p><strong>Magasin :</strong> ' . esc($this->returnStore($order_data['store_id'])) . '</p>
|
|
</div>
|
|
<div>
|
|
<p><strong>Nom:</strong> ' . esc($order_data['customer_name']) . '</p>
|
|
<p><strong>Adresse:</strong> ' . esc($order_data['customer_address']) . '</p>
|
|
<p><strong>Téléphone:</strong> ' . esc($order_data['customer_phone']) . '</p>
|
|
<p><strong>CIN:</strong> ' . esc($order_data['customer_cin']) . '</p>
|
|
</div>
|
|
</div>
|
|
|
|
<table>
|
|
<thead><tr><th>Marque</th><th>Moteur</th><th>Puissance</th><th>Prix unitaire</th></tr></thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>' . esc($product_data['sku']) . '</td>
|
|
<td>' . esc($product_data['numero_de_moteur']) . '</td>
|
|
<td>' . esc($product_data['puissance']) . '</td>
|
|
<td>' . number_format($unitPrice, 2, '.', ' ') . '</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<table class="table summary">
|
|
<tr><th>Total:</th><td></td></tr>
|
|
<tr><th>TVA (20%):</th><td></td></tr>
|
|
<tr><th>Réduction:</th><td></td></tr>
|
|
<tr><th>Total à payer:</th><td><strong></strong></td></tr>
|
|
<tr><th>Statut:</th><td></td></tr>';
|
|
|
|
if (!empty($order_data['order_payment_mode'])) {
|
|
echo '<tr><th>Mode de paiement:</th><td></td></tr>';
|
|
}
|
|
|
|
if (!empty($order_data['tranche_1'])) {
|
|
echo '<tr><th>Tranche 1:</th><td></td></tr>';
|
|
}
|
|
|
|
if (!empty($order_data['tranche_2'])) {
|
|
echo '<tr><th>Tranche 2:</th><td></td></tr>';
|
|
}
|
|
|
|
echo '</table>
|
|
|
|
<div style="display: flex; justify-content: space-around; margin-top: 5%;">
|
|
<div><p style="font-weight:bold;">L\'acheteur</p></div>
|
|
<div><p style="font-weight:bold;">Le vendeur</p></div>
|
|
</div>
|
|
|
|
<div class="invoice-footer">
|
|
Merci pour votre achat !<br>
|
|
<strong style="color:white;">Original</strong>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>';
|
|
}
|
|
|
|
// --- BON DE COMMANDE : une seule fois après la boucle ---
|
|
echo '<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">
|
|
' . $style . '
|
|
</head>
|
|
<body onload="window.print()">
|
|
<div class="invoice-container">
|
|
<div class="invoice-header">BON DE COMMANDE</div>
|
|
<div class="info">
|
|
<div>
|
|
<p><strong>Commande ID :</strong> ' . esc($order_data['order_no'] ?? $order_data['bill_no']) . '</p>
|
|
<p><strong>Magasin :</strong> ' . esc($this->returnStore($order_data['store_id'])) . '</p>
|
|
</div>
|
|
<div>
|
|
<p><strong>Nom:</strong> ' . esc($order_data['customer_name']) . '</p>
|
|
<p><strong>Adresse:</strong> ' . esc($order_data['customer_address']) . '</p>
|
|
<p><strong>Téléphone:</strong> ' . esc($order_data['customer_phone']) . '</p>
|
|
<p><strong>CIN:</strong> ' . esc($order_data['customer_cin']) . '</p>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Marque</th>
|
|
<th>Moteur</th>
|
|
<th>Puissance</th>
|
|
<th>Prix</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
|
|
$total_ht = 0;
|
|
foreach ($items as $item) {
|
|
$product_data = $Products->getProductData($item['product_id']);
|
|
$total_ht += (float)$item['amount'];
|
|
echo '<tr>
|
|
<td>' . esc($product_data['sku']) . '</td>
|
|
<td>' . esc($product_data['numero_de_moteur']) . '</td>
|
|
<td><input type="text" value="' . esc($product_data['puissance']) . '" style="border:none;width:100%;outline:none;"></td>
|
|
<td style="text-align:right;">' . number_format((float)$item['amount'], 2, '.', ' ') . '</td>
|
|
</tr>';
|
|
}
|
|
|
|
$tva = $total_ht * 0.2;
|
|
$total_ttc = $total_ht + $tva - $order_data['discount'];
|
|
|
|
echo '</tbody>';
|
|
echo ' </table>
|
|
|
|
<table class="table summary">
|
|
<tr><th>Total:</th><td>' . number_format($total_ht, 2, '.', ' ') . '</td></tr>
|
|
<tr><th>TVA:</th><td>' . number_format($tva, 2, '.', ' ') . '</td></tr>
|
|
<tr><th>Réduction:</th><td>' . number_format($order_data['discount'], 2, '.', ' ') . '</td></tr>
|
|
<tr><th>Total à payer:</th><td><strong>' . number_format($total_ttc, 2, '.', ' ') . '</strong></td></tr>
|
|
</table>';
|
|
|
|
echo '<div style="display: flex; justify-content: space-around; margin-top: 5%;">
|
|
<div><p style="font-weight:bold;">L\'acheteur</p></div>
|
|
<div><p style="font-weight:bold;">Le vendeur</p></div>
|
|
</div>';
|
|
|
|
echo'<div class="invoice-footer">
|
|
Merci pour votre commande !<br>
|
|
<strong style="color:white;">Original</strong>
|
|
</div>';
|
|
echo '</div>';
|
|
echo '</body>';
|
|
echo'</html>';
|
|
}
|
|
|
|
public function print5(int $id)
|
|
{
|
|
$this->verifyRole('viewOrder');
|
|
|
|
if (! $id) {
|
|
throw new \CodeIgniter\Exceptions\PageNotFoundException();
|
|
}
|
|
|
|
// Modèles
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
$OrderItems = new OrderItems();
|
|
|
|
// Récupération des données
|
|
$order = $Orders->getOrdersData($id);
|
|
$items = $OrderItems->getOrdersItemData($id);
|
|
$company = $Company->getCompanyData(1);
|
|
$today = date('d/m/Y');
|
|
|
|
// Pré-calculs
|
|
$totalTTC = (float) $order['gross_amount'];
|
|
$totalHT = $totalTTC / 1.20;
|
|
$tva = $totalTTC - $totalHT;
|
|
$inWords = $this->numberToWords((int) round($totalTTC));
|
|
|
|
// Statut paiement
|
|
$paidLabel = $order['paid_status'] == 1 ? 'Payé' : 'Non payé';
|
|
|
|
// Début du HTML
|
|
$html = '<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Facture '.$order['bill_no'].'</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000;margin:0; padding:0; }
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; }
|
|
.header .infos { line-height:1.4; }
|
|
.header img { max-height:80px; }
|
|
.client { margin-bottom:20px; }
|
|
table { width:100%; border-collapse:collapse; margin-bottom:20px; }
|
|
th, td { border:1px solid #000; padding:6px; }
|
|
th { background:#f0f0f0; }
|
|
.right { text-align:right; }
|
|
.signature { display:flex; justify-content:space-between; margin-top:50px; }
|
|
.signature div { text-align:center; }
|
|
.conditions { page-break-before: always; padding:20px; line-height:1.5; }
|
|
</style>
|
|
</head>
|
|
<body onload="window.print()">
|
|
|
|
<div class="header">
|
|
<div class="infos">
|
|
<h2 style="margin:0;">'.esc($company['company_name']).'</h2>
|
|
<p style="margin:2px 0;"><strong>NIF :</strong> '.esc($company['NIF']).'</p>
|
|
<p style="margin:2px 0;"><strong>STAT :</strong> '.esc($company['STAT']).'</p>
|
|
<p style="margin:2px 0;"><strong>Contact :</strong> '.esc($company['phone']).' | '.esc($company['phone2']).'</p>
|
|
</div>
|
|
<div style="text-align:center;">
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo">
|
|
<p style="margin:5px 0; font-weight:bold;">Facture N° '.esc($order['bill_no']).'</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="client">
|
|
<p><strong>DOIT Nom :</strong> '.esc($order['customer_name']).'</p>
|
|
<p><strong>Adresse :</strong> '.esc($order['customer_address']).'</p>
|
|
<p><strong>CIN :</strong> '.esc($order['customer_cin']).'</p>
|
|
<p><strong>Téléphone :</strong> '.esc($order['customer_phone'] ?? '').'</p>
|
|
<p style="text-align:right;"><em>Antananarivo, le '.$today.'</em></p>
|
|
</div>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Nom</th>
|
|
<th>MARQUE</th>
|
|
<th>TYPE</th>
|
|
<th>N° Moteur</th>
|
|
<th>N° Châssis</th>
|
|
<th>Puissance (CC)</th>
|
|
<th class="right">PRIX (Ar)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
foreach ($items as $it) {
|
|
$p = $Products->getProductData($it['product_id']);
|
|
$Brand = new Brands();
|
|
$Category = new Category();
|
|
$html .= '
|
|
<tr>
|
|
<td>'.esc($p['name']).'</td>
|
|
<td>'.esc($Brand->getNameById($p['id'])).'</td>
|
|
<td>'.esc($Category->getNameById($p['categorie_id'])).'</td>
|
|
<td>'.esc($p['numero_de_moteur']).'</td>
|
|
<td>'.esc($p['chasis'] ?? '').'</td>
|
|
<td>'.esc($p['puissance']).'</td>
|
|
<td class="right">'.number_format($p['prix_vente'], 0, '', ' ').'</td>
|
|
</tr>';
|
|
}
|
|
$html .= '
|
|
</tbody>
|
|
</table>
|
|
|
|
<table>
|
|
<tr>
|
|
<td><strong>Prix (HT) :</strong></td>
|
|
<td class="right">'.number_format($totalHT, 0, '', ' ').' Ar</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>TVA (20%) :</strong></td>
|
|
<td class="right">'.number_format($tva, 0, '', ' ').' Ar</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Total (TTC) :</strong></td>
|
|
<td class="right">'.number_format($totalTTC, 0, '', ' ').' Ar</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<div style="border:1px solid #000; padding:10px; margin-bottom:30px;">
|
|
<strong>Arrêté à la somme de :</strong><br>
|
|
'.$inWords.'
|
|
</div>
|
|
|
|
<div class="signature">
|
|
<div>L\'Acheteur<br><br>__________________</div>
|
|
<div>Le Vendeur<br><br>__________________</div>
|
|
</div>
|
|
|
|
<!-- Conditions Générales avec saut de page -->
|
|
<div class="conditions">
|
|
<div style="display:flex; justify-content:space-between; align-items:center;">
|
|
<h3 style="margin:0;">Conditions Générales</h3>
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo" style="height:60px;">
|
|
</div>
|
|
<ul>
|
|
<li>Aucun accessoire (casque, rétroviseur, batterie, etc.) n’est inclus avec la moto. Si le client en a besoin, il doit les acheter séparément.</li>
|
|
<li>Le client doit vérifier soigneusement la marchandise avant de quitter notre établissement.</li>
|
|
<li>Aucun service après-vente n’est fourni.</li>
|
|
<li>La moto est vendue sans garantie, car il s’agit d’un modèle d’occasion.</li>
|
|
<li>La facture étant un document provisoire ne peut se substituer au certificat modèle (si requis) délivré au client au moment de l’achat. Il appartient à ce dernier de procéder à l’immatriculation dans le délai prévu par la loi.</li>
|
|
</ul>
|
|
<div style="text-align:center; margin-top:50px;">L’Acheteur</div>
|
|
</div>
|
|
|
|
</body>
|
|
</html>';
|
|
|
|
return $this->response->setBody($html);
|
|
}
|
|
|
|
/**
|
|
* Convertit un nombre entier en texte (français, sans décimales).
|
|
* Usage basique, pour Ariary.
|
|
*/
|
|
private function numberToWords(int $num): string
|
|
{
|
|
// Cas zéro
|
|
if ($num === 0) {
|
|
return 'zéro ariary';
|
|
}
|
|
|
|
// Tableaux de base
|
|
$units = [
|
|
'', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six',
|
|
'sept', 'huit', 'neuf', 'dix', 'onze', 'douze',
|
|
'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf'
|
|
];
|
|
$tens = [
|
|
2 => 'vingt', 3 => 'trente', 4 => 'quarante',
|
|
5 => 'cinquante', 6 => 'soixante',
|
|
7 => 'soixante-dix', 8 => 'quatre-vingt', 9 => 'quatre-vingt-dix'
|
|
];
|
|
|
|
// Fonction récursive interne (sans la monnaie)
|
|
$convert = function(int $n) use (&$convert, $units, $tens): string {
|
|
if ($n < 20) {
|
|
return $units[$n];
|
|
}
|
|
if ($n < 100) {
|
|
$d = intdiv($n, 10);
|
|
$r = $n % 10;
|
|
// 70–79 et 90–99
|
|
if ($d === 7 || $d === 9) {
|
|
$base = $d === 7 ? 60 : 80;
|
|
return $tens[$d] . ($r ? '-' . $units[$n - $base] : '');
|
|
}
|
|
// 20–69 ou 80–89
|
|
return $tens[$d] . ($r ? '-' . $units[$r] : '');
|
|
}
|
|
if ($n < 1000) {
|
|
$h = intdiv($n, 100);
|
|
$rest = $n % 100;
|
|
$hundredText = $h > 1 ? $units[$h] . ' cent' : 'cent';
|
|
// « deux cents » prend un « s » si pas de reste
|
|
if ($h > 1 && $rest === 0) {
|
|
$hundredText .= 's';
|
|
}
|
|
return $hundredText . ($rest ? ' ' . $convert($rest) : '');
|
|
}
|
|
if ($n < 1000000) {
|
|
$k = intdiv($n, 1000);
|
|
$rest = $n % 1000;
|
|
$thousandText = $k > 1 ? $convert($k) . ' mille' : 'mille';
|
|
return $thousandText . ($rest ? ' ' . $convert($rest) : '');
|
|
}
|
|
// millions et plus
|
|
$m = intdiv($n, 1000000);
|
|
$rest = $n % 1000000;
|
|
$millionText = $m > 1 ? $convert($m) . ' million' : 'million';
|
|
// pas de 's' à million en francais
|
|
return $millionText . ($rest ? ' ' . $convert($rest) : '');
|
|
};
|
|
|
|
// Construit le texte sans la monnaie, puis ajoute 'ariary' à la fin
|
|
$words = $convert($num);
|
|
return trim($words) . ' ariary';
|
|
}
|
|
|
|
public function print7(int $id)
|
|
{
|
|
$this->verifyRole('viewOrder');
|
|
|
|
if (! $id) {
|
|
throw new \CodeIgniter\Exceptions\PageNotFoundException();
|
|
}
|
|
|
|
// Modèles
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$Products = new Products();
|
|
$OrderItems = new OrderItems();
|
|
$Brand = new Brands();
|
|
$Category = new Category();
|
|
|
|
// Récupération des données
|
|
$order = $Orders->getOrdersData($id);
|
|
$items = $OrderItems->getOrdersItemData($id);
|
|
$company = $Company->getCompanyData(1);
|
|
$today = date('d/m/Y');
|
|
|
|
// Calculs totaux
|
|
$totalTTC = (float) $order['net_amount'];
|
|
$totalHT = $totalTTC / 1.20;
|
|
$tva = $totalTTC - $totalHT;
|
|
|
|
$paidLabel = $order['paid_status'] == 1 ? 'Payé' : 'Non payé';
|
|
|
|
// Démarrage du HTML
|
|
$html = '<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Bon de commande '.$order['bill_no'].'</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; }
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin:20px; }
|
|
.header .infos { line-height:1.4; }
|
|
.header img { max-height:80px; }
|
|
.client { margin:20px; }
|
|
table { width:calc(100% - 40px); margin:0 20px 20px; border-collapse:collapse; }
|
|
th, td { border:1px solid #000; padding:8px; }
|
|
th { background:#f0f0f0; }
|
|
.right { text-align:right; }
|
|
.signature { display:flex; justify-content:space-between; margin:50px 20px 20px; }
|
|
.signature div { text-align:center; }
|
|
.footer { text-align:center; margin:20px; font-size:12px; color:#666; }
|
|
.conditions { page-break-before: always; padding:20px; line-height:1.5; }
|
|
@media print {
|
|
@page { margin:1cm; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body onload="window.print()">
|
|
|
|
<div class="header">
|
|
<div class="infos">
|
|
<h2 style="margin:0;">'.esc($company['company_name']).'</h2>
|
|
<p style="margin:2px 0;"><strong>NIF :</strong> '.esc($company['NIF']).'</p>
|
|
<p style="margin:2px 0;"><strong>STAT :</strong> '.esc($company['STAT']).'</p>
|
|
<p style="margin:2px 0;"><strong>Contact :</strong> '.esc($company['phone']).' | '.esc($company['phone2']).'</p>
|
|
</div>
|
|
<div style="text-align:center;">
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo">
|
|
<p style="margin:5px 0; font-weight:bold;">Bon de commande N° '.esc($order['bill_no']).'</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="client">
|
|
<p><strong>Client :</strong> '.esc($order['customer_name']).'</p>
|
|
<p><strong>Adresse :</strong> '.esc($order['customer_address']).'</p>
|
|
<p><strong>Téléphone :</strong> '.esc($order['customer_phone']).'</p>
|
|
<p><strong>CIN :</strong> '.esc($order['customer_cin']).'</p>
|
|
<p style="text-align:right;"><em>Antananarivo, le '.$today.'</em></p>
|
|
</div>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Nom</th>
|
|
<th>Marque</th>
|
|
<th>Catégorie</th>
|
|
<th>N° Moteur</th>
|
|
<th>Châssis</th>
|
|
<th>Puissance (CC)</th>
|
|
<th class="right">Prix Unitaire (Ar)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>';
|
|
|
|
foreach ($items as $item) {
|
|
$p = $Products->getProductData($item['product_id']);
|
|
$html .= '<tr>
|
|
<td>'.esc($p['name']).'</td>
|
|
<td>'.esc($Brand->getNameById($p['brand_id'] ?? $p['id'])).'</td>
|
|
<td>'.esc($Category->getNameById($p['categorie_id'])).'</td>
|
|
<td>'.esc($p['numero_de_moteur']).'</td>
|
|
<td>'.esc($p['chasis'] ?? '').'</td>
|
|
<td>'.esc($p['puissance']).'</td>
|
|
<td class="right">'.number_format($p['prix_vente'], 0, '', ' ').'</td>
|
|
</tr>';
|
|
}
|
|
|
|
$html .= '
|
|
</tbody>
|
|
</table>
|
|
|
|
<table style="width:calc(100% - 40px); margin:0 20px 20px;">
|
|
<tr>
|
|
<td><strong>Total HT :</strong></td>
|
|
<td class="right"> Ar</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>TVA (20%) :</strong></td>
|
|
<td class="right"> Ar</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Total TTC :</strong></td>
|
|
<td class="right"> Ar</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Statut :</strong></td>
|
|
<td class="right"></td>
|
|
</tr>';
|
|
|
|
if (! empty($order['order_payment_mode'])) {
|
|
$html .= '<tr>
|
|
<td><strong>Mode de paiement :</strong></td>
|
|
<td class="right">'.esc($order['order_payment_mode']).'</td>
|
|
</tr>';
|
|
}
|
|
|
|
$html .= '
|
|
</table>
|
|
|
|
|
|
<div class="signature">
|
|
<div>L\'acheteur<br><br>__________________</div>
|
|
<div>Le vendeur<br><br>__________________</div>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
Merci pour votre confiance
|
|
</div>
|
|
|
|
<!-- Conditions Générales avec saut de page -->
|
|
<div class="conditions">
|
|
<div style="display:flex; justify-content:space-between; align-items:center;">
|
|
<h3 style="margin:0;">Conditions Générales</h3>
|
|
<img src="'.base_url('assets/images/company_logo.jpg').'" alt="Logo" style="height:60px;">
|
|
</div>
|
|
<ul>
|
|
<li>Aucun accessoire (casque, rétroviseur, batterie, etc.) n’est inclus avec la moto. Si le client en a besoin, il doit les acheter séparément.</li>
|
|
<li>Le client doit vérifier soigneusement la marchandise avant de quitter notre établissement.</li>
|
|
<li>Aucun service après-vente n’est fourni.</li>
|
|
<li>La moto est vendue sans garantie, car il s’agit d’un modèle d’occasion.</li>
|
|
<li>La facture étant un document provisoire ne peut se substituer au certificat modèle (si requis) délivré au client au moment de l’achat. Il appartient à ce dernier de procéder à l’immatriculation dans le délai prévu par la loi.</li>
|
|
</ul>
|
|
<div style="text-align:center; margin-top:50px;">L’Acheteur</div>
|
|
</div>
|
|
|
|
</body>
|
|
</html>';
|
|
|
|
// Affichage final
|
|
echo $html;
|
|
}
|
|
|
|
|
|
public function print31(int $id)
|
|
{
|
|
// Vérification du rôle
|
|
$this->verifyRole('viewOrder');
|
|
|
|
if (! $id) {
|
|
return $this->response->setStatusCode(400, 'ID manquant');
|
|
}
|
|
|
|
// Instanciation des modèles
|
|
$Orders = new Orders();
|
|
$Company = new Company();
|
|
$OrderItems = new OrderItems();
|
|
$Products = new Products();
|
|
$Brand = new Brands();
|
|
$Category = new Category();
|
|
|
|
// Récupération des données
|
|
$order_data = $Orders->getOrdersData($id);
|
|
$items = $OrderItems->getOrdersItemData($id);
|
|
$company_info = $Company->getCompanyData(1);
|
|
|
|
// Statut de paiement
|
|
$paid_status = $order_data['paid_status'] === 1
|
|
? "<span style='color: green; font-weight: bold;'>Payé</span>"
|
|
: "<span style='color: red; font-weight: bold;'>Non payé</span>";
|
|
|
|
// STYLE COMMUN avec page-break-after
|
|
|
|
|
|
|
|
// --- FACTURES : Une par produit ---
|
|
foreach ($items as $item) {
|
|
$p = $Products->getProductData($item['product_id']);
|
|
$unitPrice = (float) $item['amount'];
|
|
$quantity = isset($item['qty']) ? (int) $item['qty'] : 1;
|
|
$subtotal = $unitPrice * $quantity;
|
|
$vatAmount = $subtotal * 0.2;
|
|
$discount = (float) $order_data['discount'];
|
|
$totalNet = $subtotal + $vatAmount - $discount;
|
|
$inWords = $this->numberToWords((int) round($subtotal));
|
|
|
|
// Début du document
|
|
echo '<!DOCTYPE html>';
|
|
echo '<html lang="fr">';
|
|
echo '<head><meta charset="utf-8">';
|
|
echo '<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">';
|
|
echo "<style>
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; }
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; }
|
|
.header .infos { line-height:1.4; }
|
|
.header img { max-height:80px; }
|
|
.client { margin-bottom:20px; }
|
|
table { width:100%; border-collapse:collapse; margin-bottom:20px; }
|
|
th, td { border:1px solid #000; padding:6px; text-align:left; }
|
|
th { background:#f0f0f0; }
|
|
.right { text-align:right; }
|
|
.signature { display:flex; justify-content:space-between; margin-top:50px; }
|
|
.signature div { text-align:center; }
|
|
.page-break { page-break-after: always; }
|
|
@media print {
|
|
body { font-size: 14px; }
|
|
@page { margin: 1cm; }
|
|
}
|
|
</style>";
|
|
echo '</head><body onload="window.print()">';
|
|
|
|
// Wrapper pour nouvelle page
|
|
echo '<div class="page-break">';
|
|
|
|
// En-tête
|
|
echo '<div class="header">';
|
|
echo '<div class="infos">';
|
|
echo '<h2 style="margin:0;">' . esc($company_info['company_name']) . '</h2>';
|
|
echo '<p style="margin:2px 0;"><strong>NIF :</strong> ' . esc($company_info['NIF']) . '</p>';
|
|
echo '<p style="margin:2px 0;"><strong>STAT :</strong> ' . esc($company_info['STAT']) . '</p>';
|
|
echo '<p style="margin:2px 0;"><strong>Contact :</strong> ' . esc($company_info['phone']) . ' | ' . esc($company_info['phone2']) . '</p>';
|
|
echo '<p style="margin:2px 0;"><strong>Magasin :</strong> ' . esc($this->returnStore($order_data['store_id'])) . '</p>';
|
|
echo '</div>'; // infos
|
|
echo '<div style="text-align:center;">';
|
|
echo '<img src="' . base_url('assets/images/company_logo.jpg') . '" alt="Logo">';
|
|
echo '<p style="margin:5px 0; font-weight:bold;">Facture N° ' . esc($order_data['bill_no']) . '</p>';
|
|
echo '<p style="margin:5px 0;"><em>Antananarivo, le ' . date('d/m/Y') . '</em></p>';
|
|
echo '</div>'; // logo
|
|
echo '</div>'; // header
|
|
|
|
// Client
|
|
echo '<div class="client">';
|
|
echo '<p><strong>Client :</strong> ' . esc($order_data['customer_name']) . '</p>';
|
|
echo '<p><strong>Adresse :</strong> ' . esc($order_data['customer_address']) . '</p>';
|
|
echo '<p><strong>Téléphone :</strong> ' . esc($order_data['customer_phone']) . '</p>';
|
|
echo '<p><strong>CIN :</strong> ' . esc($order_data['customer_cin']) . '</p>';
|
|
echo '</div>';
|
|
|
|
// Tableau produits
|
|
echo '<table><thead><tr>';
|
|
echo '<th>Nom</th><th>Marque</th><th>Catégorie</th><th>N° Moteur</th><th>Châssis</th><th>Puissance (CC)</th><th class="right">Prix Unit. (Ar)</th>';
|
|
echo '</tr></thead><tbody>';
|
|
echo '<tr>';
|
|
echo '<td>' . esc($p['name']) . '</td>';
|
|
echo '<td>' . esc($Brand->getNameById($p['id'])) . '</td>';
|
|
echo '<td>' . esc($Category->getNameById($p['categorie_id'])) . '</td>';
|
|
echo '<td>' . esc($p['numero_de_moteur']) . '</td>';
|
|
echo '<td>' . esc($p['chasis'] ?? '') . '</td>';
|
|
echo '<td>' . esc($p['puissance']) . '</td>';
|
|
echo '<td class="right">' . number_format($p['prix_vente'], 0, '', ' ') . '</td>';
|
|
echo '</tr></tbody></table>';
|
|
|
|
// Totaux
|
|
echo '<table>';
|
|
echo '<tr><td><strong>Total HT :</strong></td><td class="right">' . number_format($subtotal, 0, '.', ' ') . ' Ar</td></tr>';
|
|
echo '<tr><td><strong>TVA (20%) :</strong></td><td class="right">' . number_format($vatAmount, 0, '.', ' ') . ' Ar</td></tr>';
|
|
echo '<tr><td><strong>Réduction :</strong></td><td class="right">' . number_format($discount, 0, '.', ' ') . ' Ar</td></tr>';
|
|
echo '<tr><td><strong>Total Net :</strong></td><td class="right">' . number_format($totalNet, 0, '.', ' ') . ' Ar</td></tr>';
|
|
echo '<tr><td><strong>Statut :</strong></td><td class="right">' . $paid_status . '</td></tr>';
|
|
echo '</table>';
|
|
echo '<div style="border:1px solid #000; padding:10px; margin-bottom:30px;">
|
|
<strong>Arrêté à la somme de :</strong><br>
|
|
'.$inWords.'
|
|
</div>';
|
|
|
|
|
|
// Signature
|
|
echo '<div class="signature">';
|
|
echo '<div>L'Acheteur<br><br>__________________</div>';
|
|
echo '<div>Le Vendeur<br><br>__________________</div>';
|
|
echo '</div>';
|
|
|
|
echo '</div>'; // page-break
|
|
echo '</body></html>';
|
|
}
|
|
|
|
// --- BON DE COMMANDE : une seule fois après la boucle ---
|
|
echo '<!DOCTYPE html>';
|
|
echo '<html lang="fr">';
|
|
echo '<head><meta charset="utf-8">';
|
|
echo '<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '">';
|
|
echo "<style>
|
|
body { font-family: Arial, sans-serif; font-size:14px; color:#000; margin:0; padding:0; }
|
|
.header { display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; }
|
|
.header .infos { line-height:1.4; }
|
|
.header img { max-height:80px; }
|
|
.client { margin-bottom:20px; }
|
|
table { width:100%; border-collapse:collapse; margin-bottom:20px; }
|
|
th, td { border:1px solid #000; padding:6px; text-align:left; }
|
|
th { background:#f0f0f0; }
|
|
.right { text-align:right; }
|
|
.signature { display:flex; justify-content:space-between; margin-top:50px; }
|
|
.signature div { text-align:center; }
|
|
.page-break { page-break-after: always; }
|
|
@media print {
|
|
body { font-size: 14px; }
|
|
@page { margin: 1cm; }
|
|
}
|
|
</style>";
|
|
echo '</head><body onload="window.print()">';
|
|
|
|
// Wrapper bon de commande
|
|
echo '<div class="page-break">';
|
|
echo '<div class="header">';
|
|
echo '<div class="infos">';
|
|
echo '<h2 style="margin:0;">' . esc($company_info['company_name']) . '</h2>';
|
|
echo '<p style="margin:2px 0;"><strong>Commande ID :</strong> ' . esc($order_data['order_no'] ?? $order_data['bill_no']) . '</p>';
|
|
echo '<p style="margin:2px 0;"><strong>Magasin :</strong> ' . esc($this->returnStore($order_data['store_id'])) . '</p>';
|
|
echo '</div>';
|
|
echo '<div style="text-align:center;">';
|
|
echo '<img src="' . base_url('assets/images/company_logo.jpg') . '" alt="Logo">';
|
|
echo '<p style="margin:5px 0; font-weight:bold;">Bon de commande N° ' . esc($order_data['order_no'] ?? $order_data['bill_no']) . '</p>';
|
|
echo '<p style="margin:5px 0;"><em>Antananarivo, le ' . date('d/m/Y') . '</em></p>';
|
|
echo '</div>';
|
|
echo '</div>'; // header
|
|
|
|
// Corps bon de commande
|
|
echo '<div class="client">';
|
|
echo '<p><strong>Client :</strong> ' . esc($order_data['customer_name']) . '</p>';
|
|
echo '<p><strong>Adresse :</strong> ' . esc($order_data['customer_address']) . '</p>';
|
|
echo '<p><strong>Téléphone :</strong> ' . esc($order_data['customer_phone']) . '</p>';
|
|
echo '<p><strong>CIN :</strong> ' . esc($order_data['customer_cin']) . '</p>';
|
|
echo '</div>';
|
|
|
|
echo '<table><thead><tr>';
|
|
echo '<th>Nom</th><th>Marque</th><th>Catégorie</th><th>N° Moteur</th><th>Châssis</th><th>Puissance (CC)</th><th class="right">Prix Unit. (Ar)</th>';
|
|
echo '</tr></thead><tbody>';
|
|
$total_ht = 0;
|
|
foreach ($items as $item) {
|
|
$p = $Products->getProductData($item['product_id']);
|
|
$amount = (float) $item['amount'];
|
|
$total_ht += $amount;
|
|
echo '<tr>';
|
|
echo '<td>' . esc($p['name']) . '</td>';
|
|
echo '<td>' . esc($Brand->getNameById($p['id'])) . '</td>';
|
|
echo '<td>' . esc($Category->getNameById($p['categorie_id'])) . '</td>';
|
|
echo '<td>' . esc($p['numero_de_moteur']) . '</td>';
|
|
echo '<td>' . esc($p['chasis'] ?? '') . '</td>';
|
|
echo '<td>' . esc($p['puissance']) . '</td>';
|
|
echo '<td class="right">' . number_format($amount, 0, '', ' ') . '</td>';
|
|
echo '</tr>';
|
|
}
|
|
$tva = $total_ht * 0.2;
|
|
$total_ttc = $total_ht + $tva - (float) $order_data['discount'];
|
|
|
|
echo '</tbody></table>';
|
|
echo '<table>';
|
|
echo '<tr><td><strong>Total HT :</strong></td><td class="right">Ar</td></tr>';
|
|
echo '<tr><td><strong>TVA :</strong></td><td class="right"> Ar</td></tr>';
|
|
echo '<tr><td><strong>Réduction :</strong></td><td class="right">Ar</td></tr>';
|
|
echo '<tr><td><strong>Total TTC :</strong></td><td class="right"> Ar</td></tr>';
|
|
echo '</table>';
|
|
|
|
echo '<div class="signature">';
|
|
echo '<div>L\'Acheteur<br><br>__________________</div>';
|
|
echo '<div>Le Vendeur<br><br>__________________</div>';
|
|
echo '</div>';
|
|
|
|
|
|
// --- 3) CONDITIONS GÉNÉRALES (avec rupture AVANT) ---
|
|
echo '<div style="page-break-before: always; break-before: page; padding:20px; line-height:1.5;">';
|
|
echo '<div style="display:flex; justify-content:space-between; align-items:center;">';
|
|
echo '<h3 style="margin:0;">Conditions Générales</h3>';
|
|
echo '<img src="' . base_url('assets/images/company_logo.jpg') . '" alt="Moto" style="height:60px;">';
|
|
echo '</div>';
|
|
echo '<p>* Aucun accessoire (casque, rétroviseur, batterie, etc.) n\'est inclus avec la moto. '
|
|
. 'Si le client en a besoin, il doit les acheter séparément.</p>';
|
|
echo '<p>* Le client doit s\'assurer de vérifier soigneusement la marchandise avant de quitter notre établissement.</p>';
|
|
echo '<p>* Aucun service après-vente n\'est fourni.</p>';
|
|
echo '<p>* La moto est vendue sans garantie, car il s\'agit d\'un modèle d\'occasion.</p>';
|
|
echo '<p>* La facture étant un document provisoire ne peut se substituer au certificat modèle (si requis) '
|
|
. 'délivré au client au moment de l\'achat. Il appartient à ce dernier de procéder à l\'immatriculation '
|
|
. 'dans le délai prévu par la loi.</p>';
|
|
echo '<div style="text-align:center; margin-top:50px;">L\'Acheteur</div>';
|
|
echo '</div>';
|
|
|
|
echo '</body></html>';
|
|
}
|
|
|
|
}
|
|
|