From 3e97c9f4181475acab5de67538e74b8763773578 Mon Sep 17 00:00:00 2001 From: Luis Ernesto Portillo Zaldivar Date: Wed, 16 Jul 2025 09:12:28 -0600 Subject: [PATCH] feat(#60): Mejorar control y trazabilidad de re-muestreos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Respetar configuración del wizard (checkbox crear re-muestra) - Prevenir creación de múltiples re-muestras activas - Agregar campos para trazabilidad completa: - root_sample_id: muestra original de la cadena - resample_chain_count: total de re-muestreos en cadena - Validar límite de re-muestreos por cadena completa - Mejorar vista con información de trazabilidad - Método auxiliar para contar re-muestreos recursivamente 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../__pycache__/sale_order.cpython-312.pyc | Bin 14960 -> 15232 bytes lims_management/models/stock_lot.py | 92 ++++++++++++++++-- lims_management/views/stock_lot_views.xml | 11 ++- .../wizards/sample_rejection_wizard.py | 8 +- 4 files changed, 95 insertions(+), 16 deletions(-) diff --git a/lims_management/models/__pycache__/sale_order.cpython-312.pyc b/lims_management/models/__pycache__/sale_order.cpython-312.pyc index c909f78430dc05945d08575af7e447071ba251e4..d4ff865cf24ffa38a8bb67c8997050be82c711f5 100644 GIT binary patch delta 687 zcmX|7O-vI(6rSBe*+REaTdQ5L4ha&fwW)!&KnMX2icM@n^ya~gyBoUAw%g2XA#G3^ z;}1p>Aafv5FUFJNg>doW$)lGNNg5jua`B8I9wok|DKDAtz3;tmGVhxsySD86Cd=Ij zV&KbiZX~_yvl7CGy~l~N77mv5lxeBNWYbWP z!b6Qr&x4Tlfue>s$@b#bV*N^{9?H}Z9fW3C2gq7DM=H3z+u80VLJ2ksC2AB58pro6 z4GfuZ&Xi#0>$@TtQ*)$BG@`H=R!LFSO&|^+deM{cA<8sXS}IMxU! z_ru8_-psK}RJzxEe(!WC#QEn^L17XRdpBEpmNSw$z;i*m39GiWkbIZYNZ)67aw%}XsxOi3(O zC`c?yR7fo@NmR%$N=ePD3h>KU$VjYI$Snm576BFDRH~;CkYA*bmROcwq@$3WpO= 0 and self.resample_count >= max_attempts: - raise UserError(_('Se ha alcanzado el número máximo de re-muestreos (%d) para esta muestra.') % max_attempts) + # Find the original sample (root of the resample chain) + original_sample = self + while original_sample.parent_sample_id: + original_sample = original_sample.parent_sample_id + + # Count all resamples in the chain + total_resamples = self._count_all_resamples_in_chain(original_sample) + + # Check maximum resample attempts based on the entire chain + if max_attempts > 0 and total_resamples >= max_attempts: + raise UserError(_('Se ha alcanzado el número máximo de re-muestreos (%d) para esta cadena de muestras.') % max_attempts) # Calculate resample number for naming resample_number = self.resample_count + 1 @@ -483,6 +543,20 @@ class StockLot(models.Model): 'target': 'current', } + def _count_all_resamples_in_chain(self, root_sample): + """Count all resamples in the entire chain starting from root""" + count = 0 + samples_to_check = [root_sample] + + while samples_to_check: + sample = samples_to_check.pop(0) + # Add all child samples to the check list + for child in sample.child_sample_ids: + count += 1 + samples_to_check.append(child) + + return count + def _notify_resample_created(self, resample): """Notify receptionist users about the created resample""" # Find receptionist users diff --git a/lims_management/views/stock_lot_views.xml b/lims_management/views/stock_lot_views.xml index ec33607..511b425 100644 --- a/lims_management/views/stock_lot_views.xml +++ b/lims_management/views/stock_lot_views.xml @@ -91,10 +91,12 @@ - + + + @@ -103,9 +105,16 @@ + + + + diff --git a/lims_management/wizards/sample_rejection_wizard.py b/lims_management/wizards/sample_rejection_wizard.py index 9bea34b..dc2802e 100644 --- a/lims_management/wizards/sample_rejection_wizard.py +++ b/lims_management/wizards/sample_rejection_wizard.py @@ -67,12 +67,8 @@ class SampleRejectionWizard(models.TransientModel): 'rejection_notes': self.rejection_notes }) - # Call the rejection method on the sample - self.sample_id.action_reject() - - # Create new sample request if needed - if self.create_new_sample and self.sample_id.request_id: - self._create_new_sample_request() + # Call the rejection method on the sample with explicit resample creation preference + self.sample_id.action_reject(create_resample=self.create_new_sample) return {'type': 'ir.actions.act_window_close'}