feat(RepeatLine.js): Vide les champs lors de l'ajout d'une nouvelle ligne.

 feat(order-edit.twig): Ajoute le template pour modifier un devis.
♻️ refactor(order.twig): Affiche ou non le bouton modifier un devis.
 feat(CustomerController.php): Ajoute la modification d'un devis.
This commit is contained in:
Serreau Jovann
2025-07-29 11:52:57 +02:00
parent ede7326a1c
commit b9e4db3409
4 changed files with 151 additions and 2 deletions

View File

@@ -37,7 +37,6 @@ export class RepeatLine extends HTMLDivElement{
el.querySelectorAll('[name]')
.forEach(el => {
const newName = el.getAttribute('name').replace(/\[\d\]/gm, `[${index}]`);
el.setAttribute('name', newName);
});
});
@@ -55,7 +54,10 @@ export class RepeatLine extends HTMLDivElement{
this.$refs.rows.appendChild(newRow);
newRow.querySelector('input,textarea,select').focus();
newRow.querySelectorAll('input,textarea,select').forEach(el=>{
el.setAttribute('value','');
el.value = "";
})
this.updateFieldNames();
this.updateAddButton();
}

View File

@@ -202,6 +202,62 @@ class CustomerController extends AbstractController
'form' => $form->createView()
]);
}
#[Route(path: '/artemis/intranet/customer/{id}/orderEdit',name: 'artemis_intranet_customer_orderEdit',methods: ['GET', 'POST'])]
public function customerOrderEdit(?Customer $customer,Request $request,LoggerService $loggerService,EntityManagerInterface $entityManager,EventDispatcherInterface $eventDispatcher): Response
{
/** @var CustomerDevis $devis */
$devis = $entityManager->getRepository(CustomerDevis::class)->find($request->get('idDevis'));
if($request->isMethod('POST')) {
$data = $_POST;
$devis->setCreateAt(\DateTimeImmutable::createFromFormat('Y-m-d\TH:i',$data['date']));
$entityManager->persist($devis);
$lines = [];
foreach ($devis->getCustomerDevisLines() as $line) {
$lines[$line->getPos()] = $line;
}
ksort($lines);
foreach ($data['lines'] as $key => $line) {
if(isset($lines[$key])) {
/** @var CustomerDevisLine $v */
$v = $lines[$key];
$v->setContent($line['description']);
$v->setPriceHT($line['price']);
$v->setName($line['title']);
$entityManager->persist($v);
$entityManager->flush();
} else {
$devisLine = new CustomerDevisLine();
$devisLine->setPos($key);
$devisLine->setName($line['title']);
$devisLine->setPriceHT($line['price']);
$devisLine->setContent($line['description']);
$devisLine->setTva(1.20);
$entityManager->persist($devisLine);
$devis->addCustomerDevisLine($devisLine);
$entityManager->persist($devis);
}
}
$entityManager->flush();
$this->addFlash("success","Mise à jour effectuée");
return $this->redirectToRoute('artemis_intranet_customer_orderEdit',['id'=>$customer->getId(),'current'=>'order','idDevis'=>$devis->getId(),'type'=>'devis']);
}
$lines = [];
foreach ($devis->getCustomerDevisLines() as $line) {
$lines[$line->getPos()] =[
'title' => $line->getName(),
'price' => $line->getPriceHT(),
'description' => $line->getContent(),
];
}
ksort($lines);
return $this->render('artemis/intranet/customer/order-edit.twig',[
'customer' => $customer,
'object'=> $devis,
'lines' => $lines,
'type'=> $request->query->has('type'),
]);
}
#[Route(path: '/artemis/intranet/customer/{id}/orderAdd',name: 'artemis_intranet_customer_orderAdd',methods: ['GET', 'POST'])]
public function customerOrder(?Customer $customer,Request $request,LoggerService $loggerService,EntityManagerInterface $entityManager,EventDispatcherInterface $eventDispatcher): Response

View File

@@ -0,0 +1,86 @@
{% extends 'artemis/base.twig' %}
{% block title %}Intranet - Client - {{ customer.raisonSocial }} - Modification {{ object.numDevis }}{% endblock %}
{% block content %}
<div class="flex justify-between items-center mb-6">
<h2 class="text-3xl font-semibold text-gray-800 dark:text-gray-200">Client - {{ customer.raisonSocial }} - Modification {{ object.numDevis }}</h2>
</div>
<form method="post" class="mt-5 bg-gray-800 rounded-lg shadow-lg p-6 space-y-4">
<div class="flex space-x-4">
<div class="flex-1">
<div class="mb-5">
<label for="num" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Numéro</label>
<input type="text" name="num" id="num_devis" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required value="{{ object.numDevis }}" />
</div>
</div>
<div class="flex-1">
<div class="mb-5">
<label for="date" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Date</label>
<input type="datetime-local" name="date" id="date" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required value="{{ object.createAt|date('Y-m-d') }}T{{ object.createAt|date('h:i') }}" />
</div>
</div>
</div>
<fieldset class="form-section">
<legend>
<h2>Ligne(s)</h2>
</legend>
<div class="form-repeater" data-component="repeater" is="repeat-line">
<ol class="form-repeater__rows" data-ref="rows" tabindex="0">
{% for line in lines %}
<li class="form-repeater__row">
<fieldset class="form-group form-group--horizontal">
<div class="flex space-x-4">
<div class="flex-1">
<div class="form-field">
<div class="mb-1">
<label for="titre" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Titre</label>
<input {% if line is defined%}value="{{ line.title }}"{% endif%} type="text" name="lines[{{ (loop.index-1) }}][title]" id="lines[{{ (loop.index-1) }}][title]" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required />
</div>
<div class="mb-1">
<label for="price" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Prix HT</label>
<input {% if line is defined%}value="{{ line.price }}"{% endif%} type="number" step="0.1" name="lines[{{ (loop.index-1) }}][price]" id="lines[{{ (loop.index-1) }}][price]" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required />
</div>
<button
class="w-full form-repeater__remove-button bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded"
data-ref="removeButton"
type="button"
>
Supprimer la ligne
</button>
</div>
</div>
<div class="flex-1">
<div class="form-field">
<div class="mb-5">
<label for="description" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Description</label>
<textarea rows="7" type="text" name="lines[{{ (loop.index-1) }}][description]" id="lines[{{ (loop.index-1) }}][description]" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required>{% if line is defined%}{{ line['description'] }}{% endif%}</textarea>
</div>
</div>
</div>
</div>
</fieldset>
</li>
{% endfor %}
</ol>
<button
class="form-repeater__add-button w-full bg-purple-600 hover:bg-purple-700 text-white px-3 py-1 rounded"
data-ref="addButton"
type="button"
>
+ Ajouter une ligne
</button>
</div>
</fieldset>
<button
class="w-full bg-purple-600 hover:bg-purple-700 text-white px-3 py-1 rounded"
type="submit"
>
Enregistrer
</button>
</form>
{% endblock %}

View File

@@ -73,7 +73,12 @@
{% if orderDevi.state == "send" %}
<a href="{{ path('artemis_intranet_customer_view',{id:customer.id,current:'order',idDevis:orderDevi.id,act:'resend'}) }}" class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded">Réenvoyée le devis</a>
{% endif %}
{% if orderDevi.state == "accepted" %}
<a href="{{ path('artemis_intranet_customer_view',{id:customer.id,current:'order',idDevis:orderDevi.id,act:'createAvisPayment'}) }}" class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded">Crée l'avis de paiement</a>
{% endif %}
{% if orderDevi.state != "accepted" %}
<button class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded">Modifier</button>
{% endif %}
<a href="{{ vich_uploader_asset(orderDevi,'devis') }}" download="devis-{{ orderDevi.numDevis }}.pdf" class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded">Télécharger</a>
<button class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded">Annulée</button>
</td>