This commit is contained in:
2026-01-20 16:13:52 +01:00
parent 0fc80958af
commit e5e76e2dcb

View File

@@ -68,126 +68,202 @@ class AutomationCron(ModelSQL, ModelView):
t.FintradeBookingKey, t.FintradeBookingKey,
)) ))
# Préparer les listes pour la sauvegarde et les données du shipment # ---- PREMIÈRE TRANSACTION : Création des objets de référence ----
parties_to_save = [] with Transaction().new_transaction() as trans1:
vessels_to_save = [] try:
locations_to_save = [] parties_to_save = []
shipments_data = [] # <-- nouvelle liste vessels_to_save = []
locations_to_save = []
parties_cache = {}
vessels_cache = {}
locations_cache = {}
# Collecter les données des objets de référence
rows = cursor.fetchall()
for row in rows:
(
si_number, si_date, si_quantity, si_unit,
container_number, container_type,
loading_name, destination_name,
agent_name, carrier_name,
vessel_name, bl_number,
etd_date, bl_date, controller,
comments, fintrade_booking_key
) = row
parties_cache = {} # Fonction pour obtenir ou créer un Party
vessels_cache = {} def get_or_create_party(name):
locations_cache = {} if not name:
return None
name_upper = name.upper()
if name_upper in parties_cache:
return parties_cache[name_upper]
# Chercher d'abord dans la base
existing = Party.search([('name', '=', name_upper)], limit=1)
if existing:
parties_cache[name_upper] = existing[0]
return existing[0]
# Créer un nouveau
new_p = Party()
new_p.name = name_upper
parties_cache[name_upper] = new_p
parties_to_save.append(new_p)
return new_p
rows = cursor.fetchall() # Fonction pour obtenir ou créer un Vessel
for row in rows: def get_or_create_vessel(name):
( if not name:
si_number, si_date, si_quantity, si_unit, return None
container_number, container_type, name_upper = name.upper()
loading_name, destination_name, if name_upper in vessels_cache:
agent_name, carrier_name, return vessels_cache[name_upper]
vessel_name, bl_number,
etd_date, bl_date, controller, existing = Vessel.search([('vessel_name', '=', name_upper)], limit=1)
comments, fintrade_booking_key if existing:
) = row vessels_cache[name_upper] = existing[0]
return existing[0]
new_v = Vessel()
new_v.vessel_name = name_upper
vessels_cache[name_upper] = new_v
vessels_to_save.append(new_v)
return new_v
logger.info("ROW_FROM_CRON: %s", row) # Fonction pour obtenir ou créer une Location
def get_or_create_location(name, type_):
if not name:
return None
key = f"{name.upper()}_{type_}"
if key in locations_cache:
return locations_cache[key]
existing = Location.search([
('name', '=', name.upper()),
('type', '=', type_)
], limit=1)
if existing:
locations_cache[key] = existing[0]
return existing[0]
new_loc = Location()
new_loc.name = name.upper()
new_loc.type = type_
locations_cache[key] = new_loc
locations_to_save.append(new_loc)
return new_loc
# ----- Fonctions pour créer ou récupérer les objets ----- # Collecter les objets à créer
def get_or_create_party(name): _ = get_or_create_party(carrier_name)
name_upper = name.upper() _ = get_or_create_party(agent_name)
if name_upper in parties_cache: _ = get_or_create_vessel(vessel_name)
return parties_cache[name_upper] _ = get_or_create_location(loading_name, 'supplier')
existing = Party.search([('name', '=', name_upper)], limit=1) _ = get_or_create_location(destination_name, 'customer')
if existing:
parties_cache[name_upper] = existing[0]
return existing[0]
if name:
new_p = Party()
new_p.name = name_upper
parties_cache[name_upper] = new_p
parties_to_save.append(new_p)
return new_p
def get_or_create_vessel(name, imo=None): # Sauvegarder tous les objets de référence
name_upper = name.upper() if parties_to_save:
if name_upper in vessels_cache: Party.save(parties_to_save)
return vessels_cache[name_upper] if vessels_to_save:
existing = Vessel.search([('vessel_name', '=', name_upper)], limit=1) Vessel.save(vessels_to_save)
if existing: if locations_to_save:
vessels_cache[name_upper] = existing[0] Location.save(locations_to_save)
return existing[0]
if name: trans1.commit()
new_v = Vessel() logger.info("Première transaction commitée : objets de référence créés")
new_v.vessel_name = name_upper
new_v.vessel_imo = imo except Exception as e:
vessels_cache[name_upper] = new_v trans1.rollback()
vessels_to_save.append(new_v) logger.error(f"Erreur dans la première transaction : {e}")
return new_v raise
def get_or_create_location(name, type_): # ---- DEUXIÈME TRANSACTION : Création des shipments ----
key = f"{name.upper()}_{type_}" with Transaction().new_transaction() as trans2:
if key in locations_cache: try:
return locations_cache[key] # Recréer les curseurs après la nouvelle transaction
existing = Location.search([('name', '=', name.upper()), ('type', '=', type_)], limit=1) cursor2 = Transaction().connection.cursor()
if existing: cursor2.execute(*t.select(
locations_cache[key] = existing[0] t.ShippingInstructionNumber,
return existing[0] t.ShippingInstructionDate,
if name: t.ShippingInstructionQuantity,
new_loc = Location() t.ShippingInstructionQuantityUnit,
new_loc.name = name.upper() t.NumberOfContainers,
new_loc.type = type_ t.ContainerType,
locations_cache[key] = new_loc t.Loading,
locations_to_save.append(new_loc) t.Destination,
return new_loc t.BookingAgent,
t.Carrier,
t.Vessel,
t.BL_Number,
t.ETD_Date,
t.BL_Date,
t.ExpectedController,
t.Comments,
t.FintradeBookingKey,
))
# ----- Récupération ou création des objets ----- rows2 = cursor2.fetchall()
carrier = get_or_create_party(carrier_name) shipments_to_save = []
agent = get_or_create_party(agent_name)
vessel = get_or_create_vessel(vessel_name) for row in rows2:
loc_from = get_or_create_location(loading_name, 'supplier') (
loc_to = get_or_create_location(destination_name, 'customer') si_number, si_date, si_quantity, si_unit,
container_number, container_type,
loading_name, destination_name,
agent_name, carrier_name,
vessel_name, bl_number,
etd_date, bl_date, controller,
comments, fintrade_booking_key
) = row
# Stocker les données pour la deuxième étape # Vérifier si le shipment existe déjà
shipments_data.append({ existing_shipment = ShipmentIn.search([
'si_number': si_number, ('reference', '=', si_number)
'bl_number': bl_number, ], limit=1)
'bl_date': bl_date,
'etd_date': etd_date, if existing_shipment:
'carrier': carrier, logger.info(f"Shipment existe déjà : {si_number}")
'agent': agent, continue
'vessel': vessel,
'from_location': loc_from,
'to_location': loc_to,
})
# ----- Étape 1 : sauvegarde des objets de référence ----- # Récupérer les objets (maintenant ils existent dans la base)
if parties_to_save: carrier = Party.search([('name', '=', carrier_name.upper())], limit=1) if carrier_name else None
Party.save(parties_to_save) agent = Party.search([('name', '=', agent_name.upper())], limit=1) if agent_name else None
if vessels_to_save: vessel = Vessel.search([('vessel_name', '=', vessel_name.upper())], limit=1) if vessel_name else None
Vessel.save(vessels_to_save) loc_from = Location.search([
if locations_to_save: ('name', '=', loading_name.upper()),
Location.save(locations_to_save) ('type', '=', 'supplier')
], limit=1) if loading_name else None
loc_to = Location.search([
('name', '=', destination_name.upper()),
('type', '=', 'customer')
], limit=1) if destination_name else None
# Commit pour garantir que tous les IDs sont corrects # Créer le shipment
Transaction().commit() shipment = ShipmentIn()
shipment.reference = si_number
shipment.from_location = loc_from[0] if loc_from else None
shipment.to_location = loc_to[0] if loc_to else None
shipment.carrier = carrier[0] if carrier else None
shipment.supplier = agent[0] if agent else None
shipment.vessel = vessel[0] if vessel else None
shipment.cargo_mode = 'bulk'
shipment.bl_number = bl_number
shipment.bl_date = bl_date
shipment.etd = etd_date
shipments_to_save.append(shipment)
logger.info(f"Shipment préparé : {si_number}")
# ----- Étape 2 : création des shipments ----- # Sauvegarder tous les shipments
for data in shipments_data: if shipments_to_save:
si_number = data['si_number'] ShipmentIn.save(shipments_to_save)
shipment = ShipmentIn.search([('reference', '=', si_number)], limit=1) logger.info(f"{len(shipments_to_save)} shipments créés")
if shipment:
sh = shipment[0] trans2.commit()
else:
sh = ShipmentIn() except Exception as e:
sh.reference = si_number trans2.rollback()
sh.from_location = data['from_location'] logger.error(f"Erreur dans la deuxième transaction : {e}")
sh.to_location = data['to_location'] raise
sh.carrier = data['carrier']
sh.supplier = data['agent']
sh.vessel = data['vessel']
sh.cargo_mode = 'bulk'
sh.bl_number = data['bl_number']
sh.bl_date = data['bl_date']
sh.etd = data['etd_date']
ShipmentIn.save([sh])
logger.info("SHIPMENT_CREATED: %s", sh)