feat(#60): Agregar visualización de re-muestras en órdenes de laboratorio
- Agregar campo computed all_sample_ids que incluye re-muestras - Método recursivo para obtener todas las re-muestras - Mejorar vista de orden con pestaña unificada de muestras - Mostrar indicador de re-muestra y muestra original - Incluir estado y motivo de rechazo en la vista 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1e079a896b
commit
b225fa0815
Binary file not shown.
|
@ -33,6 +33,31 @@ class SaleOrder(models.Model):
|
|||
help="Muestras de laboratorio generadas automáticamente cuando se confirmó esta orden"
|
||||
)
|
||||
|
||||
all_sample_ids = fields.Many2many(
|
||||
'stock.lot',
|
||||
string='Todas las Muestras (inc. Re-muestras)',
|
||||
compute='_compute_all_samples',
|
||||
help="Todas las muestras relacionadas con esta orden, incluyendo re-muestras"
|
||||
)
|
||||
|
||||
@api.depends('generated_sample_ids', 'generated_sample_ids.child_sample_ids')
|
||||
def _compute_all_samples(self):
|
||||
"""Compute all samples including resamples"""
|
||||
for order in self:
|
||||
all_samples = order.generated_sample_ids
|
||||
# Add all resamples recursively
|
||||
resamples = self.env['stock.lot']
|
||||
for sample in order.generated_sample_ids:
|
||||
resamples |= self._get_all_resamples(sample)
|
||||
order.all_sample_ids = all_samples | resamples
|
||||
|
||||
def _get_all_resamples(self, sample):
|
||||
"""Recursively get all resamples of a sample"""
|
||||
resamples = sample.child_sample_ids
|
||||
for resample in sample.child_sample_ids:
|
||||
resamples |= self._get_all_resamples(resample)
|
||||
return resamples
|
||||
|
||||
def action_confirm(self):
|
||||
"""Override to generate laboratory samples and tests automatically"""
|
||||
res = super(SaleOrder, self).action_confirm()
|
||||
|
|
|
@ -29,26 +29,42 @@
|
|||
</xpath>
|
||||
<!-- Add Generated Samples tab -->
|
||||
<xpath expr="//notebook" position="inside">
|
||||
<page string="Muestras Generadas" name="generated_samples" invisible="not is_lab_request">
|
||||
<group>
|
||||
<field name="generated_sample_ids" nolabel="1" readonly="1">
|
||||
<list string="Muestras Generadas" create="false" edit="false" delete="false">
|
||||
<page string="Muestras" name="all_samples" invisible="not is_lab_request">
|
||||
<group string="Todas las Muestras (incluyendo Re-muestras)">
|
||||
<field name="all_sample_ids" nolabel="1" readonly="1">
|
||||
<list string="Todas las Muestras" create="false" edit="false" delete="false">
|
||||
<field name="name" string="Código de Muestra"/>
|
||||
<field name="barcode" string="Código de Barras"/>
|
||||
<field name="barcode" string="Código de Barras" optional="show"/>
|
||||
<field name="sample_type_product_id" string="Tipo de Muestra"/>
|
||||
<field name="volume_ml" string="Volumen (ml)"/>
|
||||
<field name="analysis_names" string="Análisis"/>
|
||||
<field name="state" string="Estado"/>
|
||||
<field name="volume_ml" string="Volumen (ml)" optional="show"/>
|
||||
<field name="analysis_names" string="Análisis" optional="show"/>
|
||||
<field name="is_resample" string="Es Re-muestra" widget="boolean_toggle"/>
|
||||
<field name="parent_sample_id" string="Muestra Original" optional="show"/>
|
||||
<field name="state" string="Estado" widget="badge"
|
||||
decoration-success="state == 'analyzed'"
|
||||
decoration-info="state == 'in_process'"
|
||||
decoration-danger="state == 'rejected'"
|
||||
decoration-warning="state == 'pending_collection'"/>
|
||||
<field name="rejection_reason_id" string="Motivo Rechazo" optional="show"/>
|
||||
<button name="action_collect" string="Recolectar" type="object"
|
||||
class="btn-primary" invisible="state != 'pending_collection'"/>
|
||||
class="btn-sm btn-primary" invisible="state != 'pending_collection'"/>
|
||||
</list>
|
||||
</field>
|
||||
</group>
|
||||
<group invisible="not generated_sample_ids">
|
||||
<div class="alert alert-info" role="alert">
|
||||
<p>Las muestras han sido generadas automáticamente basándose en los análisis solicitados.
|
||||
Cada muestra agrupa los análisis que requieren el mismo tipo de contenedor.</p>
|
||||
</div>
|
||||
<group string="Resumen" col="4">
|
||||
<field name="generated_sample_ids" invisible="1"/>
|
||||
<group>
|
||||
<label for="generated_sample_ids" string="Muestras Originales:"/>
|
||||
<div>
|
||||
<span class="badge badge-primary"><field name="generated_sample_ids" readonly="1" widget="many2many_tags"/></span>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<div class="alert alert-info" role="alert">
|
||||
<p><i class="fa fa-info-circle"/> Las muestras han sido generadas automáticamente basándose en los análisis solicitados.</p>
|
||||
<p>Las re-muestras se generan cuando una muestra es rechazada.</p>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
|
|
Loading…
Reference in New Issue
Block a user