You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							211 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							211 lines
						
					
					
						
							11 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| ############################################################################### | |
| # | |
| #    Cybrosys Technologies Pvt. Ltd. | |
| # | |
| #    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | |
| #    Author: Ayana kp(odoo@cybrosys.com) | |
| # | |
| #    This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1) | |
| #    It is forbidden to publish, distribute, sublicense, or sell copies of the | |
| #    Software or modified copies of the Software. | |
| # | |
| #    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| #    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| #    FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | |
| #    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER | |
| #    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING | |
| #    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| #    DEALINGS IN THE SOFTWARE. | |
| # | |
| ############################################################################### | |
| import logging | |
| from markupsafe import Markup | |
| from zeep.helpers import serialize_object | |
| from odoo import models, _ | |
| from odoo.exceptions import UserError | |
| from odoo.tools import pdf | |
| from odoo.addons.delivery_fedex.models.fedex_request import FedexRequest, \ | |
|   _convert_curr_iso_fdx | |
| 
 | |
| _logger = logging.getLogger(__name__) | |
| 
 | |
| 
 | |
| class DeliveryCarrier(models.Model): | |
|     """This class inherits from the base delivery carrier model and | |
|     allows for additional customization and functionality to be added | |
|     to delivery carriers. """ | |
|     _inherit = "delivery.carrier" | |
| 
 | |
|     def fedex_send_shipping(self, picking): | |
|         """Overriding default fedex integration function to | |
|         check with our condition""" | |
|         if picking.batch_id and not picking.carrier_tracking_ref: | |
|             partner_id = picking.partner_id.id | |
|             carrier_id = picking.carrier_id.id | |
|             filtered_picking_ids = picking.batch_id.picking_ids.filtered( | |
|                 lambda | |
|                     x: x.partner_id.id == partner_id and x.carrier_id.id == carrier_id) | |
|             # Now you have filtered_picking_ids with the desired records | |
|             if len(filtered_picking_ids) > 1: | |
|                 response = self._batch_fedex_send_shipping(picking, | |
|                                                            filtered_picking_ids) | |
|                 return response | |
|             else: | |
|                 res = super().fedex_send_shipping(picking) | |
|                 return res | |
|         else: | |
|             res = super().fedex_send_shipping(picking) | |
|             return res | |
| 
 | |
|     def _batch_fedex_send_shipping(self, picking, filtered_picking_ids): | |
|         """ Function for batch transfers picking to connect fedex and return | |
|         same tracking numbers for all picking with same | |
|         carrier id and customer. """ | |
|         res = [] | |
|         order_currency = picking.sale_id.currency_id or picking.company_id.currency_id | |
|         srm = FedexRequest(self.log_xml, request_type="shipping", | |
|                            prod_environment=self.prod_environment) | |
|         superself = self.sudo() | |
|         srm.web_authentication_detail(superself.fedex_developer_key, | |
|                                       superself.fedex_developer_password) | |
|         srm.client_detail(superself.fedex_account_number, | |
|                           superself.fedex_meter_number) | |
|         srm.transaction_detail(picking.id) | |
|         package_type = picking.package_ids and picking.package_ids[ | |
|             0].package_type_id.shipper_package_code or self.fedex_default_package_type_id.shipper_package_code | |
|         srm.shipment_request(self.fedex_droppoff_type, self.fedex_service_type, | |
|                              package_type, self.fedex_weight_unit, | |
|                              self.fedex_saturday_delivery) | |
|         srm.set_currency(_convert_curr_iso_fdx(order_currency.name)) | |
|         srm.set_shipper(picking.company_id.partner_id, | |
|                         picking.picking_type_id.warehouse_id.partner_id) | |
|         srm.set_recipient(picking.partner_id) | |
|         srm.shipping_charges_payment(superself.fedex_account_number) | |
|         srm.shipment_label('COMMON2D', self.fedex_label_file_type, | |
|                            self.fedex_label_stock_type, | |
|                            'TOP_EDGE_OF_TEXT_FIRST', 'SHIPPING_LABEL_FIRST') | |
|         order = picking.sale_id | |
|         net_weight = 0.0 | |
|         if 'INTERNATIONAL' in self.fedex_service_type or self.fedex_service_type == 'FEDEX_REGIONAL_ECONOMY' or ( | |
|                 picking.partner_id.country_id.code == 'IN' and picking.picking_type_id.warehouse_id.partner_id.country_id.code == 'IN'): | |
|             commodities = self._get_commodities_from_stock_move_lines( | |
|                 picking.move_line_ids) | |
|             for commodity in commodities: | |
|                 srm.commodities(self, commodity, | |
|                                 _convert_curr_iso_fdx(order_currency.name)) | |
| 
 | |
|             total_commodities_amount = sum( | |
|                 c.monetary_value * c.qty for c in commodities) | |
|             srm.customs_value(_convert_curr_iso_fdx(order_currency.name), | |
|                               total_commodities_amount, "NON_DOCUMENTS") | |
|             srm.duties_payment(order.warehouse_id.partner_id, | |
|                                superself.fedex_account_number, | |
|                                superself.fedex_duty_payment) | |
|             send_etd = superself.env['ir.config_parameter'].get_param( | |
|                 "delivery_fedex.send_etd") | |
|             srm.commercial_invoice(self.fedex_document_stock_type, send_etd) | |
|         package_count = 1 | |
|         packages = [] | |
|         package_ids = [] | |
|         for pick in filtered_picking_ids: | |
|             if not pick.carrier_tracking_ref: | |
|                 if pick.package_ids not in package_ids: | |
|                     package_ids.append(pick.package_ids) | |
|                     converted_weight = self._fedex_convert_weight( | |
|                         pick.shipping_weight, self.fedex_weight_unit) | |
|                     package_count += len(pick.package_ids) | |
|                     package = self._get_packages_from_picking(pick, | |
|                                                               self.fedex_default_package_type_id) | |
|                     packages.append(package) | |
|         if isinstance(converted_weight, (int, float)): | |
|             net_weight += converted_weight | |
|         po_number = order.display_name or False | |
|         dept_number = False | |
|         if picking.partner_id.country_id.code == 'IN' and picking.picking_type_id.warehouse_id.partner_id.country_id.code == 'IN': | |
|             po_number = 'B2B' if picking.partner_id.commercial_partner_id.is_company else 'B2C' | |
|             dept_number = 'BILL D/T: SENDER' | |
|         master_tracking_id = False | |
|         package_labels = [] | |
|         carrier_tracking_refs = [] | |
|         flattened_packages = [item for sublist in packages for item in sublist] | |
|         for sequence, package in enumerate(flattened_packages, start=1): | |
|             srm.add_package( | |
|                 self, | |
|                 package, | |
|                 _convert_curr_iso_fdx(package.company_id.currency_id.name), | |
|                 sequence_number=sequence, | |
|                 po_number=po_number, | |
|                 dept_number=dept_number, | |
|                 reference=picking.display_name, | |
|             ) | |
|             srm.set_master_package(net_weight, len(flattened_packages), | |
|                                    master_tracking_id=master_tracking_id) | |
|             self._fedex_update_srm(srm, 'ship', picking=picking) | |
|             request = serialize_object( | |
|                 dict(WebAuthenticationDetail=srm.WebAuthenticationDetail, | |
|                      ClientDetail=srm.ClientDetail, | |
|                      TransactionDetail=srm.TransactionDetail, | |
|                      VersionId=srm.VersionId, | |
|                      RequestedShipment=srm.RequestedShipment)) | |
|             self._fedex_add_extra_data_to_request(request, 'ship') | |
|             response = srm.process_shipment(request) | |
|             warnings = response.get('warnings_message') | |
|             if warnings: | |
|                 _logger.info(warnings) | |
|             if response.get('errors_message'): | |
|                 raise UserError(response['errors_message']) | |
|             package_name = package.name or 'package-' + str(sequence) | |
|             package_labels.append((package_name, srm.get_label())) | |
|             carrier_tracking_refs.append(response['tracking_number']) | |
|             if sequence == 1: | |
|                 master_tracking_id = response['master_tracking_id'] | |
|             # Last package | |
|             if sequence == len(flattened_packages): | |
|                 carrier_price = self._get_request_price(response['price'], | |
|                                                         order, | |
|                                                         order_currency) | |
|                 if self.fedex_label_file_type != 'PDF': | |
|                     attachments = [('%s-%s.%s' % ( | |
|                         self._get_delivery_label_prefix(), pl[0], | |
|                         self.fedex_label_file_type), pl[1]) for pl in | |
|                                    package_labels] | |
|                 if self.fedex_label_file_type == 'PDF': | |
|                     attachments = [ | |
|                         ('%s.pdf' % (self._get_delivery_label_prefix()), | |
|                          pdf.merge_pdf( | |
|                              [pl[1] for pl in package_labels]))] | |
|                 num = 0 | |
|                 for pick in filtered_picking_ids: | |
|                     if not pick.carrier_tracking_ref and num < len( | |
|                             carrier_tracking_refs): | |
|                         logmessage = Markup( | |
|                             _("Shipment created into Fedex<br/>" | |
|                               "<b>Tracking Numbers:</b> %s<br/>" | |
|                               "<b>Packages:</b> %s")) % ( | |
|                                          carrier_tracking_refs[num], | |
|                                          pick.package_ids.name) | |
|                         num += 1 | |
|                         pick.message_post(body=logmessage, | |
|                                           attachments=attachments) | |
|                 shipping_data = {'exact_price': carrier_price, | |
|                                  'tracking_number': ','.join( | |
|                                      carrier_tracking_refs)} | |
|                 res = res + [shipping_data] | |
|                 logmessage = Markup(_("Shipment created into Fedex<br/>" | |
|                                       "<b>Tracking Numbers:</b> %s<br/>" | |
|                                       "<b>Packages:</b> %s")) % ( | |
|                                  ','.join(carrier_tracking_refs), | |
|                                  ','.join([pl[0] for pl in package_labels])) | |
|                 if self.fedex_label_file_type != 'PDF': | |
|                     attachments = [('%s-%s.%s' % ( | |
|                         self._get_delivery_label_prefix(), pl[0], | |
|                         self.fedex_label_file_type), pl[1]) for pl in | |
|                                    package_labels] | |
|                 if self.fedex_label_file_type == 'PDF': | |
|                     attachments = [('%s.pdf' % ( | |
|                         self._get_delivery_label_prefix()), pdf.merge_pdf( | |
|                         [pl[1] for pl in package_labels]))] | |
|                 picking.batch_id.message_post(body=logmessage, | |
|                                               attachments=attachments) | |
|         return res
 | |
| 
 |