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"
|
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):
|
def action_confirm(self):
|
||||||
"""Override to generate laboratory samples and tests automatically"""
|
"""Override to generate laboratory samples and tests automatically"""
|
||||||
res = super(SaleOrder, self).action_confirm()
|
res = super(SaleOrder, self).action_confirm()
|
||||||
|
|
|
@ -29,26 +29,42 @@
|
||||||
</xpath>
|
</xpath>
|
||||||
<!-- Add Generated Samples tab -->
|
<!-- Add Generated Samples tab -->
|
||||||
<xpath expr="//notebook" position="inside">
|
<xpath expr="//notebook" position="inside">
|
||||||
<page string="Muestras Generadas" name="generated_samples" invisible="not is_lab_request">
|
<page string="Muestras" name="all_samples" invisible="not is_lab_request">
|
||||||
<group>
|
<group string="Todas las Muestras (incluyendo Re-muestras)">
|
||||||
<field name="generated_sample_ids" nolabel="1" readonly="1">
|
<field name="all_sample_ids" nolabel="1" readonly="1">
|
||||||
<list string="Muestras Generadas" create="false" edit="false" delete="false">
|
<list string="Todas las Muestras" create="false" edit="false" delete="false">
|
||||||
<field name="name" string="Código de Muestra"/>
|
<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="sample_type_product_id" string="Tipo de Muestra"/>
|
||||||
<field name="volume_ml" string="Volumen (ml)"/>
|
<field name="volume_ml" string="Volumen (ml)" optional="show"/>
|
||||||
<field name="analysis_names" string="Análisis"/>
|
<field name="analysis_names" string="Análisis" optional="show"/>
|
||||||
<field name="state" string="Estado"/>
|
<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"
|
<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>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</group>
|
</group>
|
||||||
<group invisible="not generated_sample_ids">
|
<group string="Resumen" col="4">
|
||||||
<div class="alert alert-info" role="alert">
|
<field name="generated_sample_ids" invisible="1"/>
|
||||||
<p>Las muestras han sido generadas automáticamente basándose en los análisis solicitados.
|
<group>
|
||||||
Cada muestra agrupa los análisis que requieren el mismo tipo de contenedor.</p>
|
<label for="generated_sample_ids" string="Muestras Originales:"/>
|
||||||
</div>
|
<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>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user