Merge PR #294 into 16.0

Signed-off-by hparfr
This commit is contained in:
OCA-git-bot
2024-07-23 08:14:09 +00:00
8 changed files with 556 additions and 0 deletions

View File

@@ -0,0 +1 @@
../../../../stock_picking_batch_report

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)

View File

@@ -0,0 +1,88 @@
==========================
Stock Picking Batch Report
==========================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--reporting-lightgray.png?logo=github
:target: https://github.com/OCA/stock-logistics-reporting/tree/12.0/stock_picking_product_label
:alt: OCA/stock-logistics-reporting
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/stock-logistics-reporting-12-0/stock-logistics-reporting-12-0-stock_picking_product_label
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/151/12.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows users to print batch picking.
**Table of contents**
.. contents::
:local:
Usage
=====
This module will aggregate pickings by location in Batch.
Also It will have picking details.
Note: It will work only for 2 step delivery.
Guidelines for use:
* In a Batch Transfer, press the Print Batch Transfer.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-reporting/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/stock-logistics-reporting/issues/new?body=module:%20stock_picking_product_label%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Open Source Integrators
Contributors
~~~~~~~~~~~~
* Chanakya Soni <csoni@opensourceintegrators.com>
* Maxime Chambreuil <mchambreuil@opensourceintegrators.com>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
This module is part of the `OCA/stock-logistics-reporting <https://github.com/OCA/stock-logistics-reporting/tree/12.0/stock_picking_product_label>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,4 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models

View File

@@ -0,0 +1,16 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Stock Picking Batch Report",
"version": "16.0.1.0.0",
"author": "Open Source Integrators, " "Odoo Community Association (OCA)",
"license": "AGPL-3",
"summary": "Stock Picking Batch Report",
"category": "Stock",
"maintainer": "Open Source Integrators",
"website": "https://github.com/OCA/stock-logistics-reporting",
"depends": ["stock_picking_batch"],
"data": ["reports/report_picking_batch.xml"],
"installable": True,
}

View File

@@ -0,0 +1,4 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import stock_picking_batch

View File

@@ -0,0 +1,11 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class StockPikcingBatch(models.Model):
_inherit = "stock.picking.batch"
def get_out_pickings(self):
return self.mapped("move_ids.move_dest_ids.picking_id")

View File

@@ -0,0 +1,426 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="stock_picking_batch.report_picking_batch">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t
t-set="move_line_ids"
t-value="o.picking_ids.mapped('move_line_ids').sorted(lambda line: (line.location_id.display_name, line.product_id.name))"
/>
<t
t-set="has_serial_number"
t-value="move_line_ids.filtered('lot_id')"
groups="stock.group_production_lot"
/>
<t
t-set="has_uom"
t-value="move_line_ids.filtered('product_uom_id')"
groups="uom.group_uom"
/>
<t t-call="web.external_layout">
<div class="page">
<div class="d-flex">
<div><h3>Batch : <span t-field="o.name" /></h3></div>
<div class="mr-auto">
<img
alt="Barcode"
t-att-src="'/report/barcode/?barcode_type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('Code128', quote_plus(o.name or ''), 600, 150)"
style="width:300px;height:50px"
/>
</div>
</div>
<div t-if="o.user_id">
<strong>Responsible:</strong>
<span t-field="o.user_id" />
</div><br />
<table class="table table-condensed">
<thead>
<tr>
<th width="27%">Location</th>
<th>Product</th>
<th t-if="has_serial_number" width="15%">
<strong>Lot/Serial Number</strong>
</th>
<th>Quantity</th>
<th width="23%">Transfer</th>
</tr>
</thead>
<tbody>
<tr t-foreach="move_line_ids" t-as="move_operation">
<td>
<span
t-esc="move_operation.mapped('location_id').display_name"
/>
</td>
<td>
<span
t-field="move_operation.display_name"
/>
</td>
<td
t-if="has_serial_number"
class="text-center h6"
width="15%"
>
<img
t-if="move_operation.lot_id or move_operation.lot_name"
t-att-src="'/report/barcode/?barcode_type=%s&amp;value=%s&amp;width=%s&amp;height=%s&amp;humanreadable=1' % ('Code128', move_operation.lot_id.name, 600, 100)"
style="width:100%;height:35px;"
alt="Barcode"
/>
</td>
<td>
<t t-if="not has_package">
<t
t-if="move_operation.state == 'done'"
>
<span
t-esc="sum(move_operation.mapped('qty_done'))"
/>
</t>
<t t-else="">
<span
t-esc="sum(move_operation.mapped('move_id.product_uom_qty'))"
/>
</t>
</t>
<t t-if="has_package">
<span
t-esc="sum(move_operation.mapped('qty_done'))"
/>
</t>
<span
t-field="move_operation.product_uom_id"
groups="uom.group_uom"
/>
</td>
<td>
<span
t-esc="move_operation.mapped('picking_id').display_name"
/>
</td>
</tr>
</tbody>
</table>
<p style="page-break-after: always;" />
<t t-set="pickings" t-value="o.get_out_pickings()" />
<t t-foreach="pickings" t-as="picking">
<t
t-set="picking"
t-value="picking.with_context(lang=picking.partner_id.lang)"
/>
<t
t-set="partner"
t-value="picking.partner_id or (picking.move_ids and picking.move_ids[0].partner_id) or False"
/>
<t t-if="partner" name="partner_header">
<div class="row">
<div class="col-5 offset-7">
<div
t-esc="partner"
t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True}'
/>
</div>
</div>
</t>
<div class="page">
<h2>
<span t-field="picking.name" />
</h2>
<div class="row mt32 mb32">
<div
t-if="picking.origin"
class="col-auto"
name="div_origin"
>
<strong>Order:</strong>
<p t-field="picking.origin" />
</div>
<div
t-if="picking.state"
class="col-auto"
name="div_sched_date"
>
<strong>Shipping Date:</strong>
<t t-if="picking.state == 'done'">
<p t-field="picking.date_done" />
</t>
<t t-if="picking.state != 'done'">
<p t-field="picking.scheduled_date" />
</t>
</div>
<div
t-if="picking.picking_type_id.code == 'outgoing' and picking.carrier_id"
class="col-auto"
>
<strong>Carrier:</strong>
<p t-field="picking.carrier_id" />
</div>
</div>
<table
class="table table-sm"
t-if="picking.state!='done'"
name="stock_move_table"
>
<thead>
<tr>
<th name="th_sm_product"><strong
>Product</strong></th>
<th name="th_sm_quantity"><strong
>Quantity</strong></th>
</tr>
</thead>
<tbody>
<t
t-set="lines"
t-value="picking.move_ids.filtered(lambda x: x.product_uom_qty)"
/>
<tr t-foreach="lines" t-as="move">
<td>
<span t-field="move.product_id" />
<p
t-if="move.description_picking != move.product_id.name"
>
<span
t-field="move.description_picking"
/>
</p>
</td>
<td>
<span
t-field="move.product_uom_qty"
/>
<span t-field="move.product_uom" />
</td>
</tr>
</tbody>
</table>
<table
class="table table-sm mt48"
t-if="picking.move_line_ids and picking.state=='done'"
name="stock_move_line_table"
>
<t t-set="has_serial_number" t-value="False" />
<t
t-set="has_serial_number"
t-value="picking.move_line_ids.mapped('lot_id')"
groups="stock.group_lot_on_delivery_slip"
/>
<thead>
<tr>
<th name="th_sml_product"><strong
>Product</strong></th>
<t
name="lot_serial"
t-if="has_serial_number"
>
<th>
Lot/Serial Number
</th>
</t>
<th
name="th_sml_quantity"
class="text-center"
><strong>Quantity</strong></th>
</tr>
</thead>
<tbody>
<!-- This part gets complicated with different use cases (additional use cases in extensions of this report):
1. If serial numbers are used and set to print on delivery slip => print lines as is, otherwise group them by overlapping
product + description + uom combinations
2. If any packages are assigned => split products up by package (or non-package) and then apply use case 1 -->
<!-- If has destination packages => create sections of corresponding products -->
<t
t-if="picking.has_packages"
name="has_packages"
>
<t
t-set="packages"
t-value="picking.move_line_ids.mapped('result_package_id')"
/>
<t t-foreach="packages" t-as="package">
<t
t-call="stock.stock_report_delivery_package_section_line"
/>
<t
t-set="package_move_lines"
t-value="picking.move_line_ids.filtered(lambda l: l.result_package_id == package)"
/>
<!-- If printing lots/serial numbers => keep products in original lines -->
<t t-if="has_serial_number">
<tr
t-foreach="package_move_lines"
t-as="move_line"
>
<t
t-call="stock.stock_report_delivery_has_serial_move_line"
/>
</tr>
</t>
<!-- If not printing lots/serial numbers => merge lines with same product+description+uom -->
<t t-else="">
<t
t-set="aggregated_lines"
t-value="package_move_lines._get_aggregated_product_quantities()"
/>
<t
t-call="stock.stock_report_delivery_aggregated_move_lines"
/>
</t>
</t>
<!-- Make sure we do another section for package-less products if they exist -->
<t
t-set="move_lines"
t-value="picking.move_line_ids.filtered(lambda l: not l.result_package_id)"
/>
<t
t-if="move_lines"
name="no_package_move_lines"
>
<t
t-call="stock.stock_report_delivery_no_package_section_line"
name="no_package_section"
/>
<t t-if="has_serial_number">
<tr
t-foreach="move_lines"
t-as="move_line"
>
<t
t-call="stock.stock_report_delivery_has_serial_move_line"
/>
</tr>
</t>
<t t-else="">
<t
t-set="aggregated_lines"
t-value="move_lines._get_aggregated_product_quantities()"
/>
<t t-if="aggregated_lines">
<t
t-call="stock.stock_report_delivery_aggregated_move_lines"
/>
</t>
</t>
</t>
</t>
<!-- No destination packages -->
<t t-else="">
<!-- If printing lots/serial numbers => keep products in original lines -->
<t t-if="has_serial_number">
<tr
t-foreach="picking.move_line_ids"
t-as="move_line"
>
<t
t-call="stock.stock_report_delivery_has_serial_move_line"
/>
</tr>
</t>
<!-- If not printing lots/serial numbers => merge lines with same product -->
<t
t-else=""
name="aggregated_move_lines"
>
<t
t-set="aggregated_lines"
t-value="picking.move_line_ids._get_aggregated_product_quantities()"
/>
<t
t-call="stock.stock_report_delivery_aggregated_move_lines"
/>
</t>
</t>
</tbody>
</table>
<t
t-set="backorders"
t-value="picking.backorder_ids.filtered(lambda x: x.state not in ('done', 'cancel'))"
/>
<t t-if="picking.backorder_ids and backorders">
<p>
<span
>All items couldn't be shipped, the following items will be shipped as soon as they become available.</span>
</p>
<table
class="table table-sm"
name="stock_backorder_table"
>
<thead>
<tr>
<th name="th_sb_product"><strong
>Product</strong></th>
<th
name="th_sb_quantity"
class="text-center"
><strong>Quantity</strong></th>
</tr>
</thead>
<tbody>
<t
t-foreach="backorders"
t-as="backorder"
>
<t
t-set="bo_lines"
t-value="backorder.move_ids.filtered(lambda x: x.product_uom_qty)"
/>
<tr
t-foreach="bo_lines"
t-as="bo_line"
>
<td>
<span
t-field="bo_line.product_id"
/>
<p
t-if="bo_line.description_picking != bo_line.product_id.name"
>
<span
t-field="bo_line.description_picking"
/>
</p>
</td>
<td class="text-center">
<span
t-field="bo_line.product_uom_qty"
/>
<span
t-field="bo_line.product_uom"
/>
</td>
</tr>
</t>
</tbody>
</table>
</t>
<div
t-if="picking.signature"
class="mt32 ml64 mr4"
name="signature"
>
<div class="offset-8">
<strong>Signature</strong>
</div>
<div class="offset-8">
<img
t-att-src="image_data_uri(picking.signature)"
style="max-height: 4cm; max-width: 8cm;"
/>
</div>
<div class="offset-8 text-center">
<p t-field="picking.partner_id.name" />
</div>
</div>
</div>
<p style="page-break-after: always;" />
</t>
</div>
</t>
</t>
</t>
</template>
</odoo>