diff --git a/Build/Autoupdater.fbpInf b/Build/Autoupdater.fbpInf index 8dbbd76..92b4b32 100644 --- a/Build/Autoupdater.fbpInf +++ b/Build/Autoupdater.fbpInf @@ -14,8 +14,8 @@ - 00:00:19 - 17/04/2024 10:26:10 - True + 00:00:14 + 28/02/2025 10:14:30 + False diff --git a/Build/Autoupdater.fbz6 b/Build/Autoupdater.fbz6 index c91e2de..053c6ac 100644 Binary files a/Build/Autoupdater.fbz6 and b/Build/Autoupdater.fbz6 differ diff --git a/Build/Build.fbl6 b/Build/Build.fbl6 index c4fdae0..db36662 100644 Binary files a/Build/Build.fbl6 and b/Build/Build.fbl6 differ diff --git a/Build/Build.fbpInf b/Build/Build.fbpInf index 8b9ff39..17e04e9 100644 --- a/Build/Build.fbpInf +++ b/Build/Build.fbpInf @@ -14,8 +14,8 @@ - 00:00:00 - 18/12/2023 12:40:28 - False + 00:03:39 + 08/05/2025 9:43:42 + True diff --git a/Build/Build.fbz6 b/Build/Build.fbz6 index 33b7992..2bc6543 100644 Binary files a/Build/Build.fbz6 and b/Build/Build.fbz6 differ diff --git a/Build/Installer.fbl6 b/Build/Installer.fbl6 index 260bedc..ba00cac 100644 Binary files a/Build/Installer.fbl6 and b/Build/Installer.fbl6 differ diff --git a/Build/UploadFTP.fbpInf b/Build/UploadFTP.fbpInf index d704401..b13a642 100644 --- a/Build/UploadFTP.fbpInf +++ b/Build/UploadFTP.fbpInf @@ -10,8 +10,8 @@ - 00:00:01 - 16/04/2024 18:27:15 - True + 00:00:00 + 28/02/2025 10:12:54 + False diff --git a/Build/UploadFTP.fbz6 b/Build/UploadFTP.fbz6 index 35002d3..fa3b203 100644 Binary files a/Build/UploadFTP.fbz6 and b/Build/UploadFTP.fbz6 differ diff --git a/Source/ApplicationBase/ApplicationBase.dpk b/Source/ApplicationBase/ApplicationBase.dpk index a878e44..963633d 100644 --- a/Source/ApplicationBase/ApplicationBase.dpk +++ b/Source/ApplicationBase/ApplicationBase.dpk @@ -138,6 +138,7 @@ contains schIdiomasServer_Intf in 'Idiomas\Model\schIdiomasServer_Intf.pas', uDataModuleIdiomas in 'Idiomas\Data\uDataModuleIdiomas.pas', uIDataModuleIdiomas in 'Idiomas\Model\Data\uIDataModuleIdiomas.pas', - uIdiomasController in 'Idiomas\Controller\uIdiomasController.pas'; + uIdiomasController in 'Idiomas\Controller\uIdiomasController.pas', + uPlugins_Intf in 'uPlugins_Intf.pas'; end. diff --git a/Source/ApplicationBase/ApplicationBase.dproj b/Source/ApplicationBase/ApplicationBase.dproj index 987cae8..5c69c66 100644 --- a/Source/ApplicationBase/ApplicationBase.dproj +++ b/Source/ApplicationBase/ApplicationBase.dproj @@ -46,21 +46,6 @@ Package FalseTrueFalseFalseFalseFalseTrueFalse1000FalseFalseFalseFalseFalse308212521.0.0.01.0.0.0 - - - - - - - - - - - - - - - RemObjects Data Abstract - SQLite Driver Microsoft Office 2000 Sample Automation Server Wrapper Components Microsoft Office XP Sample Automation Server Wrapper Components @@ -71,6 +56,43 @@ MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -161,44 +183,7 @@
frViewTiendas
TCustomView
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -207,6 +192,7 @@ + diff --git a/Source/ApplicationBase/Idiomas/Model/uBizIdiomas.pas b/Source/ApplicationBase/Idiomas/Model/uBizIdiomas.pas index dc7365a..5437ed6 100644 --- a/Source/ApplicationBase/Idiomas/Model/uBizIdiomas.pas +++ b/Source/ApplicationBase/Idiomas/Model/uBizIdiomas.pas @@ -8,8 +8,11 @@ uses const BIZ_CLIENT_IDIOMAS = 'Client.Idiomas'; IDIOMA_DEFAULT = 'es'; - CTE_ID_IDIOMA_DEFAULT = 2; PAIS_DEFAULT = 'España'; + CTE_ID_IDIOMA_DEFAULT = 1; + CTE_ID_IDIOMA_EN = 2; + CTE_ID_IDIOMA_FR = 3; + type IBizIdioma = interface(IIdiomas) diff --git a/Source/ApplicationBase/Idiomas/Model/uBizIdiomasServer.pas b/Source/ApplicationBase/Idiomas/Model/uBizIdiomasServer.pas index d4f7932..634cc0a 100644 --- a/Source/ApplicationBase/Idiomas/Model/uBizIdiomasServer.pas +++ b/Source/ApplicationBase/Idiomas/Model/uBizIdiomasServer.pas @@ -9,6 +9,7 @@ uses const BIZ_SERVER_IDIOMA = 'Server.Idioma'; IDIOMA_EN = 'en'; + IDIOMA_FR = 'fr'; implementation end. diff --git a/Source/ApplicationBase/uFactuGES_App.pas b/Source/ApplicationBase/uFactuGES_App.pas index e648fa7..2fba29b 100644 --- a/Source/ApplicationBase/uFactuGES_App.pas +++ b/Source/ApplicationBase/uFactuGES_App.pas @@ -5,7 +5,7 @@ interface uses SysUtils, Classes, Forms, uBizUsuarios, uBizEmpresas, uBizEjercicios, uControllerBase, uEmpresasController, uUsuariosController, uHostManager, uConfiguracionController, - uBizEmpresasTiendas; + uBizEmpresasTiendas, uModuleController; const CTE_PERFIL_ADMINISTRADOR = 3; @@ -87,6 +87,8 @@ type procedure Run; procedure Terminate; + function GetModule(AModuleName: String): TModuleController; + procedure Configurar; property AppVersion : String read GetAppVersion; @@ -180,6 +182,8 @@ type procedure Run; procedure Terminate; + function GetModule(AModuleName: String): TModuleController; + procedure Configurar; procedure SeleccionarEmpresa; @@ -435,6 +439,19 @@ begin Result := FDoLoadModulesEvent; end; +function TAppFactuGES.GetModule(AModuleName: String): TModuleController; +var + i : integer; +begin + Result := NIL; + for i := 0 to ModuleManager.ModulesCount - 1 do + if ModuleManager.Modules[i].Module.ModuleName = AModuleName then + begin + Result := ModuleManager.Modules[i].Module; + Break; + end; +end; + function TAppFactuGES.GetModuleManager: THostManager; begin Result := FHostManager; diff --git a/Source/Base/Base.res b/Source/Base/Base.res index 1641339..8b251f3 100644 Binary files a/Source/Base/Base.res and b/Source/Base/Base.res differ diff --git a/Source/Cliente/FactuGES.dproj b/Source/Cliente/FactuGES.dproj index e035a8c..313d674 100644 --- a/Source/Cliente/FactuGES.dproj +++ b/Source/Cliente/FactuGES.dproj @@ -52,18 +52,7 @@ Delphi.Personality VCLApplication -FalseTrueFalseC:\Archivos de programa\Borland\Delphi7\Bin\TrueFalse4780FalseFalseFalseFalseFalse30821252Rodax Software S.L.4.7.8.0FactuGESFactuGES4.7.8.0 - - - - - - - - - - - +FalseTrueFalseC:\Archivos de programa\Borland\Delphi7\Bin\TrueFalse4890FalseFalseFalseFalseFalse30821252Rodax Software S.L.4.8.9.0FactuGESFactuGES4.8.9.0 File C:\Documents and Settings\All Users\Documentos\RAD Studio\5.0\Bpl\dxPScxScheduler2LnkD11.bpl not found FactuGES.dprFalse @@ -86,7 +75,6 @@ - - diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dpk b/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dpk index 4fe4e4a..080d9f7 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dpk +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dpk @@ -41,7 +41,8 @@ requires AlbaranesProveedor_model, PedidosProveedor_controller, Inventario_controller, - Inventario_model; + Inventario_model, + Articulos_controller; contains uGenerarAlbaranesProvUtils in 'uGenerarAlbaranesProvUtils.pas'; diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dproj b/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dproj index 21f7be7..9daf025 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dproj +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/PedProv_AlbProv_relation.dproj @@ -57,6 +57,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -121,23 +193,24 @@ MainSource - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/uGenerarAlbaranesProvUtils.pas b/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/uGenerarAlbaranesProvUtils.pas index 56d4d95..76c3361 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/uGenerarAlbaranesProvUtils.pas +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Albaranes de proveedor/uGenerarAlbaranesProvUtils.pas @@ -4,7 +4,7 @@ interface uses Windows, SysUtils, Classes, uBizPedidosProveedor, pngimage, JSDialog, - uBizDetallesPedidoProveedor; + uBizDetallesPedidoProveedor, uBizAlbaranesProveedor, uBizInventario; type TdmGenerarAlbaranesProv = class(TDataModule) @@ -14,10 +14,12 @@ type function GenerarAlbaranProv(const IDPedido : Integer) : Boolean; overload; function GenerarAlbaranProv(APedido : IBizPedidoProveedor) : Boolean; overload; function GenerarAlbaranesProv(APedidos : IBizPedidoProveedor) : Boolean; overload; - function GenerarAlbaranProv : Boolean; overload; +// function GenerarAlbaranProv : Boolean; overload; function GenerarAlbaranesProv : Boolean; overload; function RecibirPedidoProv(APedido: IBizPedidoProveedor): Boolean; overload; function RecibirPedidoProv: Boolean; overload; + function GenerarAlbaranesdeListaPedidos(AAlbaranes: IBizAlbaranProveedor; AListaPedidos: IBizPedidoProveedor): Boolean; + function Anadir(AAlbaran : IBizAlbaranProveedor; const IDPedido : Integer; AInventarioRecibido: IBizInventario): Boolean; overload; implementation @@ -28,8 +30,10 @@ uses uPedidosProveedorController, uDetallesPedidoProveedorController, uAlbaranesProveedorController, uProveedoresController, uDetallesAlbaranProveedorController, uControllerDetallesBase, - uBizAlbaranesProveedor, uBizContactos, schPedidosProveedorClient_Intf, - schAlbaranesProveedorClient_Intf, uInventarioController, uBizInventario; + uBizContactos, schPedidosProveedorClient_Intf, + schAlbaranesProveedorClient_Intf, uInventarioController, + schInventarioClient_Intf, uArticulosController, uBizArticulos, Variants, schArticulosClient_Intf, + uDADataTable, DB, uControllerDetallesArticulos; var dmGenerarAlbaranesProv: TdmGenerarAlbaranesProv; @@ -72,8 +76,195 @@ begin AAlbaran.IMPORTE_TOTAL := APedido.IMPORTE_TOTAL; AAlbaran.DataTable.FieldByName(fld_AlbaranesProveedorOBSERVACIONES).AsVariant := APedido.DataTable.FieldByName(fld_PedidosProveedorOBSERVACIONES).AsVariant; AAlbaran.ID_FORMA_PAGO := APedido.ID_FORMA_PAGO; + AAlbaran.ID_ALMACEN := APedido.ID_ALMACEN; end; +procedure CopiarArticulosPedido(ID_PEDIDO: Integer; AOrigen: IBizDetallesPedidoProveedor; ADestino : IBizDetallesAlbaranProveedor; AArticulosPendientes: IBizDetallesPedidoProveedorPend); +var + i : integer; + ADetallesController : IDetallesAlbaranProveedorController; + ACantidad: Variant; + ArticulosAnadidosAux: TStringList; + ACadena: String; + +begin + if not Assigned(AOrigen) then + raise Exception.Create ('Origen no asignado (CopiarArticulosPedido)'); + + if not Assigned(ADestino) then + raise Exception.Create ('Destino no asignado (CopiarArticulosPedido)'); + + if not AOrigen.DataTable.Active then + AOrigen.DataTable.Active := True; + + if not ADestino.DataTable.Active then + ADestino.DataTable.Active := True; + + ADetallesController := TDetallesAlbaranProveedorController.Create; + ArticulosAnadidosAux:= TStringList.Create; + try + //OJO IMPORTANTE + //Siempre que vayamos a trabajar con los detalles debemos hacer un beginupdate de los mismos y un endupdate para + //obligarle siempre a recalcular los detalles una sola vez + ADetallesController.BeginUpdate(ADestino); + + AOrigen.DataTable.First; + for i := 0 to AOrigen.DataTable.RecordCount - 1 do + begin + ACadena := ''; + if (AOrigen.ID_ARTICULO > 1) then + begin + //Comprobamos el articulo del pedido no haya sido recibido ya en otro albaran. + AArticulosPendientes.DataTable.First; + if AArticulosPendientes.DataTable.Locate(fld_PedidosProveedor_DetallesID_ARTICULO, AOrigen.ID_ARTICULO, []) then + begin + //Esto es para el caso de meter edl mismo articulo varias veces en el pedido cambiando la descripción, si esto ocurre, + //Metemos en la primera aparición la suma de las unidades a recibir y en las siguiente apariciones se pone CERO + if (ArticulosAnadidosAux.IndexOf(IntToStr(AOrigen.ID_ARTICULO)) = -1) then + begin + ACantidad := AArticulosPendientes.CANTIDAD; + ArticulosAnadidosAux.Add(IntToStr(AOrigen.ID_ARTICULO)); + end + else begin + ACantidad := 0; + ACadena := #10 + #13 + ' - Artículo con ref. ' + AOrigen.REFERENCIA + ' repetido en otra linea y descripción diferente'; + end; + end + else + begin + ACantidad := 0; //AOrigen.CANTIDAD; + ACadena := ' - Recibido en un albarán anterior' + end; + end + else + ACantidad := AOrigen.CANTIDAD; + + ADetallesController.Add(ADestino, TIPO_DETALLE_CONCEPTO); + ADestino.Edit; + ADestino.REFERENCIA := AOrigen.REFERENCIA; + if AOrigen.ID_ARTICULO > 0 then + ADestino.ID_ARTICULO := AOrigen.ID_ARTICULO; + ADestino.CONCEPTO := AOrigen.CONCEPTO + ACadena; + ADestino.CANTIDAD := ACantidad; + ADestino.IMPORTE_UNIDAD := AOrigen.IMPORTE_UNIDAD; + ADestino.IMPORTE_TOTAL := AOrigen.IMPORTE_TOTAL; + ADestino.DESCUENTO := AOrigen.DESCUENTO; + ADestino.IMPORTE_PORTE := AOrigen.IMPORTE_PORTE; + ADestino.VISIBLE := AOrigen.VISIBLE; + ADestino.REFERENCIA_PROVEEDOR := AOrigen.REFERENCIA_PROVEEDOR; + ADestino.ID_PEDIDO := ID_PEDIDO; + ADestino.Post; + AOrigen.Next; + end; + finally + ArticulosAnadidosAux.Destroy; + ADetallesController.EndUpdate(ADestino); + ADetallesController := NIL; + end; +end; + +procedure CopiarArticulosAAlbaran(APedido: IBizPedidoProveedor; AAlbaran: IBizAlbaranProveedor; + AInventarioRecibido: IBizInventario); +var + i : integer; + ADetalles : IBizDetallesAlbaranProveedor; + ADetallesController : IDetallesAlbaranProveedorController; + AArticulosController : IArticulosController; + AArticulo : IBizArticulo; +begin + if not Assigned(AAlbaran) then + raise Exception.Create ('Albarán no asignado (CopiarArticulosAAlbaran)'); + + if not Assigned(APedido) then + raise Exception.Create ('Pedido no asignado (CopiarArticulosAAlbaran)'); + + //Si esta asignado el inventario recibido es por una entrada de articulos de un pedido a almacén + if Assigned(AInventarioRecibido) then + begin + if not AInventarioRecibido.DataTable.Active then + AInventarioRecibido.DataTable.Active := True; + + // El albarán tiene que venir ya abierto y posicionado donde hay que copiar + + ADetalles := AAlbaran.Detalles; + ADetallesController := TDetallesAlbaranProveedorController.Create; + AArticulosController := TArticulosController.Create; + try + AInventarioRecibido.DataTable.First; + for i := 0 to AInventarioRecibido.DataTable.RecordCount - 1 do + begin + AArticulo := AArticulosController.Buscar(AInventarioRecibido.ID_ARTICULO); + if not Assigned(AArticulo) then + raise Exception.Create(Format('No se ha encontrado el artículo con ID %d (CopiarArticulosAAlbaran)', [AInventarioRecibido.ID_ARTICULO])); + + if (AInventarioRecibido.CANTIDAD <> 0) then + begin + ADetallesController.Add(ADetalles, TIPO_DETALLE_CONCEPTO); +//Se cambia porque puede haber articulos del pedido que no tengan referencia de proveedor +// ADetallesController.AnadirArticulo(ADetalles, AInventarioRecibido.REFERENCIA, tCliente); + ADetallesController.AnadirArticulo(ADetalles, AInventarioRecibido.ID_ARTICULO); + ADetalles.Edit; + + APedido.Detalles.First; +//Se cambia porque puede haber articulos del pedido que no tengan referencia de proveedor +// if not APedido.Detalles.DataTable.Locate(fld_ArticulosREFERENCIA, ADetalles.REFERENCIA, []) then + if not APedido.Detalles.Locate(fld_INVENTARIOID_ARTICULO, VarArrayOf([ADetalles.DataTable.FieldByName('ID_ARTICULO').AsVariant]), []) then + raise Exception.Create(Format('No se ha encontrado el artículo del pedido con REFERENCIA %s (CopiarArticulosAAlbaran)', [ADetalles.REFERENCIA])); + ADetalles.IMPORTE_UNIDAD := APedido.Detalles.IMPORTE_UNIDAD; + ADetalles.DESCUENTO := APedido.Detalles.DESCUENTO; + ADetalles.IMPORTE_PORTE := APedido.Detalles.IMPORTE_PORTE; + + ADetalles.CANTIDAD := AInventarioRecibido.CANTIDAD; + ADetalles.Post; + end; + + AInventarioRecibido.Next; + end; + + finally + ADetallesController := NIL; + AArticulosController := NIL; + end; + end + else begin + // AInventarioRecibido = NIL + + // El albarán tiene que venir ya abierto y posicionado donde hay que copiar + + ADetalles := AAlbaran.Detalles; + ADetallesController := TDetallesAlbaranProveedorController.Create; + AArticulosController := TArticulosController.Create; + try + APedido.Detalles.DataTable.First; + for i := 0 to APedido.Detalles.DataTable.RecordCount - 1 do + begin + AArticulo := AArticulosController.Buscar(APedido.Detalles.ID_ARTICULO); + if not Assigned(AArticulo) then + raise Exception.Create(Format('No se ha encontrado el artículo con ID %d (CopiarArticulosAAlbaran)', [APedido.Detalles.ID_ARTICULO])); + + if (APedido.Detalles.CANTIDAD <> 0) then + begin + ADetallesController.Add(ADetalles, TIPO_DETALLE_CONCEPTO); + ADetallesController.AnadirArticulo(ADetalles, APedido.Detalles.REFERENCIA, tCliente); + ADetalles.Edit; + ADetalles.IMPORTE_UNIDAD := APedido.Detalles.IMPORTE_UNIDAD; + ADetalles.DESCUENTO := APedido.Detalles.DESCUENTO; + ADetalles.IMPORTE_PORTE := APedido.Detalles.IMPORTE_PORTE; + ADetalles.CANTIDAD := APedido.Detalles.CANTIDAD; + ADetalles.Post; + end; + APedido.Detalles.Next; + end; + finally + ADetallesController := NIL; + AArticulosController := NIL; + end; + end; + + ADetallesController.ActualizarTotales(ADetalles); +end; + + procedure CopiarArticulosPendAAlbaran( APedido: IBizPedidoProveedor; AAlbaran: IBizAlbaranProveedor; @@ -166,7 +357,10 @@ begin Inicializar; APedido := APedidosProveedorController.Buscar(IDPedido); - Result := GenerarAlbaranesProv(APedido); + Result := GenerarAlbaranProv(APedido); + + // Este método genera el albarán sin posibilidad de cancelar + // Result := GenerarAlbaranesProv(APedido); if Assigned(APedidosProveedorController) then Finalizar; @@ -180,6 +374,7 @@ var ARespuesta : Integer; AAlbaran : IBizAlbaranProveedor; AArticulosPendientes: IBizDetallesPedidoProveedorPend; + bEnEdicion : Boolean; begin Result := False; @@ -194,7 +389,7 @@ begin APedido.DataTable.Active := True; try - AArticulosPendientes := ADetallesPedidosProveedorController.ArticulosPendientes(APedido.ID); + AArticulosPendientes := APedidosProveedorController.ArticulosPendientesDeRecibir(APedido.ID); if not Assigned(AArticulosPendientes) then raise Exception.Create('Error al recuperar los artículos sin albarán del pedido (GenerarAlbaranProv)'); @@ -209,33 +404,76 @@ begin AAlbaran := AAlbaranesProveedorController.Nuevo; CopiarPedidoAAlbaran(APedido, AAlbaran); - CopiarArticulosPendAAlbaran(APedido, AAlbaran, AArticulosPendientes); - //Sustituir por if de guardar - if AAlbaranesProveedorController.Guardar(AAlbaran) then + //Por cada pedido a añadir lo asignamos al campo manual de referencias de pedidos asociados REF_PEDIDOS_PROV + bEnEdicion := (AAlbaran.DataTable.State in dsEditModes); + if not bEnEdicion then + AAlbaran.Edit; + AAlbaran.REF_PEDIDOS_PROV := AAlbaran.REF_PEDIDOS_PROV + ' ' + APedido.REFERENCIA; + AAlbaran.Post; + if bEnEdicion then + AAlbaran.Edit; + + AAlbaran.Detalles.DataTable.Last; + // Añado el título + ADetallesAlbaranesController.Add(AAlbaran.Detalles, TIPO_DETALLE_TITULO); + with AAlbaran.Detalles do begin -// ShowWarningMessage('Todos los artículos que contiene el pedido no están en el catálogo, y por lo tanto no se puede generar el albarán'); + Edit; + CONCEPTO := 'Pedido ' + APedido.REFERENCIA + ' del ' + DateToStr(APedido.FECHA_PEDIDO); + Post; + end; - with dmGenerarAlbaranesProv.JsListaAlbaranesGenerados do - begin - Instruction.Text := 'Se ha generado el albarán'; - Content.Clear; - Content.Add(Format('Se ha generado correctamente el albarán %s a partir del pedido de cliente' + #10#13, [AAlbaran.REFERENCIA])); - Execute; + // Añado el contenido del pedido + CopiarArticulosPedido(APedido.ID, APedido.Detalles, AAlbaran.Detalles, AArticulosPendientes); +//Cuando solo se quieren tener en cuenta los pendientes +//CopiarArticulosPendAAlbaran(APedido, AAlbaran, AArticulosPendientes); - ARespuesta := CustomButtonResult; - case ARespuesta of - 100 : begin - // Ver el albarán - AAlbaranesProveedorController.Ver(AAlbaran); - end; - 200 : // Continuar; - end; - end; + // Añado el resumen + ADetallesAlbaranesController.Add(AAlbaran.Detalles, TIPO_DETALLE_SUBTOTAL); + with AAlbaran.Detalles do + begin + Edit; + CONCEPTO := 'Total del pedido ' + APedido.REFERENCIA; + Post; + end; + + // Añado una línea en blanco + ADetallesAlbaranesController.Add(AAlbaran.Detalles, TIPO_DETALLE_CONCEPTO); + with AAlbaran.Detalles do + begin + Edit; + CONCEPTO := ''; + Post; + end; + + // Guardo el albaran que acabo de generar o editar + AAlbaran.CalcularImporteTotal; + + AAlbaranesProveedorController.Ver(AAlbaran); + + //En el caso de que haya guardado miramos si tiene el ID_PEDIDO asociado ya que en este caso la asociación lo laquitamos + //para a posteriori modificar el pedido de proveedor con el ID_ALBARAN correspondiente + if not AAlbaran.ID_PEDIDOIsNull then + begin + //28/05/2025- Stefy nos dice que un albarán puede englobar a varios pedidos por lo que la relacion 1-n estará en los pedidos +// AAlbaranes.ID_PEDIDO := AListaPedidos.ID; + // Asociamos el albarán al pedido, aunque puede darse el caso de que un pedido llegue en varios albaranes, + // en tal caso el ID que se almacena en el pedido será el último albarán, aunque en los albaranes guardamos las + // referencias de los pedidos recibidos en cada albaran por lo que siempre podremos localizar los dos albaranes + //donde se han recibido a no ser que el usuario lo borro manuelmente + APedido.Edit; + APedidosProveedorController.RecuperarProveedor(APedido); + APedido.Proveedor.DataTable.Active := True; + APedido.ID_ALBARAN := AAlbaran.ID; + APedido.REF_ALBARAN := AAlbaran.REFERENCIA; + APedido.Post; + APedidosProveedorController.Guardar(APedido); end; Result := True; finally + AAlbaran := Nil; AArticulosPendientes := NIL; if Assigned(APedidosProveedorController) then Finalizar; @@ -262,7 +500,7 @@ begin try AAlbaranesNuevos := AAlbaranesProveedorController.Nuevo(False); - if AAlbaranesProveedorController.Anadir(AAlbaranesNuevos, APedidos) then + if GenerarAlbaranesdeListaPedidos(AAlbaranesNuevos, APedidos) then begin if AAlbaranesNuevos.DataTable.RecordCount = 1 then begin @@ -292,7 +530,6 @@ begin end; end; - dmGenerarAlbaranesProv.JsListaAlbaranesGenerados.Execute; ARespuesta := dmGenerarAlbaranesProv.JsListaAlbaranesGenerados.CustomButtonResult; case ARespuesta of @@ -310,7 +547,7 @@ begin end; -function GenerarAlbaranProv : Boolean; overload; +{function GenerarAlbaranProv : Boolean; overload; //Solo generará el albarán correspondiente al pedido seleccionado var APedido : IBizPedidoProveedor; @@ -331,24 +568,24 @@ begin if Assigned(APedidosProveedorController) then Finalizar; end; -end; +end;} function GenerarAlbaranesProv : Boolean; overload; // Generara tantos albaranes como proveedores distintos tenga en la lista de pedidos seleccionada var - APedido : IBizPedidoProveedor; + APedidos : IBizPedidoProveedor; begin Result := False; try if not Assigned(APedidosProveedorController) then Inicializar; - APedido := APedidosProveedorController.ElegirPedidos(APedidosProveedorController.BuscarPendientesRecepcion, + APedidos := APedidosProveedorController.ElegirPedidos(APedidosProveedorController.BuscarPendientesRecepcion, 'Elija el pedido o pedidos de proveedor que desea utilizar para dar de alta el albarán correspondiente.' , True); - if Assigned(APedido) then - Result := GenerarAlbaranesProv(APedido); + if Assigned(APedidos) then + Result := GenerarAlbaranesProv(APedidos); finally if Assigned(APedidosProveedorController) then @@ -411,7 +648,7 @@ begin AAlbaran := AAlbaranesProveedorController.Nuevo; // En AInventarioRecibido tenemos la lista de articulos que hemos recibido y // que utilizaremos para hacer el albarán - if AAlbaranesProveedorController.Anadir(AAlbaran, APedido.ID, AInventarioRecibido) then + if Anadir(AAlbaran, APedido.ID, AInventarioRecibido) then AAlbaranesProveedorController.Ver(AAlbaran); finally AAlbaran := NIL; @@ -445,4 +682,224 @@ begin end; end; +function GenerarAlbaranesdeListaPedidos(AAlbaranes: IBizAlbaranProveedor; AListaPedidos: IBizPedidoProveedor): Boolean; +var + AAlbaranActual : IBizAlbaranProveedor; + APedidosController : IPedidosProveedorController; + AArticulosPendientes : IBizDetallesPedidoProveedorPend; + I: Integer; + bEnEdicion : Boolean; +begin + Result := False; + + // ATENCIÓN!!! AAlbaranes tiene que estar vacio para no pisar albaranes + // ya generados. + if not Assigned(AAlbaranes) then + raise Exception.Create ('Albaran no asignado (Anadir)'); + + if not Assigned(AListaPedidos) then + raise Exception.Create ('Pedidos no asignados (Anadir)'); + + if not AAlbaranes.DataTable.Active then + AAlbaranes.DataTable.Active := True; + + if not AListaPedidos.DataTable.Active then + AListaPedidos.DataTable.Active := True; + + APedidosController := TPedidosProveedorController.Create; + try + // Ordenar por fecha de pedido + AListaPedidos.DataTable.Sort([fld_PedidosProveedorFECHA_PEDIDO], [uDADataTable.sdAscending]); + AListaPedidos.First; + for I := 0 to AListaPedidos.DataTable.RecordCount - 1 do + begin + AListaPedidos._Proveedor := NIL; + AAlbaranActual := NIL; + + // Busco si hay algun albarán ya hecho de ese Proveedor + AAlbaranes.DataTable.First; + if AAlbaranes.DataTable.Locate(fld_AlbaranesProveedorID_Proveedor, AListaPedidos.ID_Proveedor, []) then + begin + AAlbaranActual := AAlbaranes; + +//Si ya tenemos un albarán quiere decir que dicho albarán va ha recibir mas de un pedido +//por lo que la relación con el pedido se traslada a los articulos detalles, es decir un albarán que recibe varios pedidos +//el idPedido de la cabeceza será null. + bEnEdicion := (AAlbaranActual.DataTable.State in dsEditModes); + if not bEnEdicion then + AAlbaranActual.Edit; + AAlbaranActual.ID_PEDIDOIsNull := True; +//Cuando elijo varios pedidos ponemos como almacén destino siempre el que tenga asociado el primer pedido del albaran +// AAlbaranActual.ID_ALMACEN := AL PASADO POR PARAMETRO + AAlbaranActual.Post; + if bEnEdicion then + AAlbaranActual.Edit; + end + else begin + // No hay albaran de ese Proveedor. Creo una nueva + AAlbaranesProveedorController.Anadir(AAlbaranes); + + //Siempre asignaremos por defecto el ID_PEDIDO del primer pedido de la lista, si hay más pedidos en el albarán luego los pondremos a null, + //con ID_ALMACEN pasará lo mismo + bEnEdicion := (AAlbaranes.DataTable.State in dsEditModes); + if not bEnEdicion then + AAlbaranes.Edit; +//28/05/2025- Stefy nos dice que un albarán puede englobar a varios pedidos por lo que la relacion 1-n estará en los pedidos +// AAlbaranes.ID_PEDIDO := AListaPedidos.ID; + AAlbaranes.ID_ALMACEN := AListaPedidos.ID_ALMACEN; + AAlbaranes.Post; + if bEnEdicion then + AAlbaranes.Edit; + + //Si el albaran es de tipo devolución hacemos la factura de tipo abono +{ if (AListaAlbaranes.TIPO = CTE_TIPO_ALBARAN_DEV) then + begin + bEnEdicion := (AFacturas.DataTable.State in dsEditModes); + if not bEnEdicion then + AFacturas.Edit; + AFacturas.TIPO := CTE_TIPO_ABONO; + AFacturas.Post; + if bEnEdicion then + AFacturas.Edit; + end; +} + AAlbaranActual := AAlbaranes; + end; + + //Asignamos el proveedor del pedido en el alñbarán siempre + APedidosController.RecuperarProveedor(AListaPedidos); + AAlbaranes.Proveedor := AListaPedidos.Proveedor; + + //Por cada pedido a añadir lo asignamos al campo manual de referencias de pedidos asociados REF_PEDIDOS_PROV + bEnEdicion := (AAlbaranActual.DataTable.State in dsEditModes); + if not bEnEdicion then + AAlbaranActual.Edit; + AAlbaranActual.REF_PEDIDOS_PROV := AAlbaranActual.REF_PEDIDOS_PROV + ' ' + AListaPedidos.REFERENCIA; + AAlbaranes.Post; + if bEnEdicion then + AAlbaranActual.Edit; + + // Ya tengo el albarán. Le añado los conceptos del pedido + //Recogemos los articulos pendientes de recibir de pedido, para solo recibir lo restante si ya estubiera recibido parcialmente. + //SOLO SE TENDRA EN CUENTA LOS INVENTARIABLES + AArticulosPendientes := APedidosController.ArticulosPendientesDeRecibir(AListaPedidos.ID); + + + AAlbaranActual.Detalles.DataTable.Last; + // Añado el título + AAlbaranesProveedorController.DetallesController.Add(AAlbaranActual.Detalles, TIPO_DETALLE_TITULO); + with AAlbaranActual.Detalles do + begin + Edit; + CONCEPTO := 'Pedido ' + AListaPedidos.REFERENCIA + ' del ' + DateToStr(AListaPedidos.FECHA_PEDIDO); + Post; + end; + + // Añado el contenido del pedido + CopiarArticulosPedido(AListaPedidos.ID, AListaPedidos.Detalles, AAlbaranActual.Detalles, AArticulosPendientes); + +{En los albaranes a proveedor el porte es a nivel del artículo + Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_CONCEPTO); + with AFacturaActual.Detalles do + begin + Edit; + CONCEPTO := 'Porte del albarán'; + CANTIDAD := 1; + IMPORTE_UNIDAD := AListaAlbaranes.IMPORTE_PORTE; + Post; + end; +} + + // Añado el resumen + AAlbaranesProveedorController.DetallesController.Add(AAlbaranActual.Detalles, TIPO_DETALLE_SUBTOTAL); + with AAlbaranActual.Detalles do + begin + Edit; + CONCEPTO := 'Total del pedido ' + AListaPedidos.REFERENCIA; + Post; + end; + + // Añado una línea en blanco + AAlbaranesProveedorController.DetallesController.Add(AAlbaranActual.Detalles, TIPO_DETALLE_CONCEPTO); + with AAlbaranActual.Detalles do + begin + Edit; + CONCEPTO := ''; + Post; + end; + + // Guardo el albaran que acabo de generar o editar + AAlbaranActual.CalcularImporteTotal; + AAlbaranesProveedorController.Guardar(AAlbaranActual); + + // Asociamos el albarán al pedido, aunque puede darse el caso de que un pedido llegue en varios albaranes, + // en tal caso el ID que se almacena en el pedido será el último albarán, aunque en los albaranes guardamos las + // referencias de los pedidos recibidos en cada albaran por lo que siempre podremos localizar los dos albaranes + //donde se han recibido a no ser que el usuario lo borro manuelmente + AListaPedidos.Edit; + AListaPedidos.ID_ALBARAN := AAlbaranActual.ID; + AListaPedidos.REF_ALBARAN := AAlbaranActual.REFERENCIA; + AListaPedidos.Post; + APedidosController.Guardar(AListaPedidos); + + AListaPedidos.Next; + end; + + + Result := True; + finally + APedidosController := NIL; + end; +end; + +function Anadir(AAlbaran: IBizAlbaranProveedor; const IDPedido: Integer; AInventarioRecibido: IBizInventario): Boolean; +var + APedidosController : TPedidosProveedorController; + APedido : IBizPedidoProveedor; +begin + Result := False; + if not Assigned(AAlbaran) then + raise Exception.Create ('Albarán no asignado (Anadir)'); + + if (IDPedido < 0) or (IDPedido = 0) then + raise Exception.Create (Format('ID de pedido (%d) incorrecto (Anadir)', [IDPedido])); + + if not AAlbaran.DataTable.Active then + AAlbaran.DataTable.Active := True; + +// ShowHourglassCursor; +// Application.ProcessMessages; + + APedido := NIL; + APedidosController := TPedidosProveedorController.Create; + try + APedido := APedidosController.Buscar(IDPedido); + if not Assigned(APedido) then + raise Exception.Create (Format('No se ha encontrado un pedido de proveedor con ID %d (Anadir)', [IDPedido])); + + APedido.DataTable.Active := True; + + if not Assigned(AInventarioRecibido) then + begin + if (APedido.ID_ALMACEN > 0) then + raise Exception.Create ('Inventario recibido no asignado (Anadir)') + end + else begin + if not AInventarioRecibido.DataTable.Active then + AInventarioRecibido.DataTable.Active := True; + end; + + AAlbaranesProveedorController.Anadir(AAlbaran); + CopiarPedidoAAlbaran(APedido, AAlbaran); + CopiarArticulosAAlbaran(APedido, AAlbaran, AInventarioRecibido); + AAlbaranesProveedorController.RecalcularImportes(AAlbaran); + Result := True; + finally + APedido := NIL; + APedidosController := NIL; +// HideHourglassCursor; +// Application.ProcessMessages; + end; +end; + end. diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dpk b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dpk index 57cd942..1642b30 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dpk +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dpk @@ -27,7 +27,6 @@ package PedProv_FacProv_relation; requires rtl, Base, - ControllerBase, Contactos_model, Contactos_controller, PNG_D10, diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dproj b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dproj index 2322789..32ceef7 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dproj +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/PedProv_FacProv_relation.dproj @@ -34,86 +34,12 @@ ..\..\..\Lib;..\..\Lib ..\..\..\Lib;..\..\Lib ..\..\..\Lib;..\..\Lib - DEBUG Delphi.Personality Package - - False - True - False - - - False - False - False - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 3082 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +FalseTrueFalseFalseFalseFalseTrueFalse1000FalseFalseFalseFalseFalse308212521.0.0.01.0.0.0 @@ -186,34 +112,511 @@ SMExport suite: data export from dataset. Written by Mike Shkolnik/Scalabium, 1998-2004. Intraweb 8.0 Design Package for Borland Development Studio 2006 Internet Explorer Components - - - PedProv_FacProv_relation.dpk - - +
PedProv_FacProv_relation.dpk
- + MainSource - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - \ No newline at end of file + + diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.dfm b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.dfm index 182262d..d119822 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.dfm +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.dfm @@ -32,7 +32,7 @@ object dmGenerarFacturasProv: TdmGenerarFacturasProv FD84C20B8417C3AA789405239826E0CBCE4F98979E10344C33B0BE630473D312 82866906D6993E62F6F1C3F45D160A5305BE68FF8095CF5B4302134CFE1185EA 1FB8A1B4FF4FE32FF6FADB8B5E0000000049454E44AE426082} - Instruction.Text = 'Se ha generado el albar'#195#161'n...' + Instruction.Text = 'Se ha/n generado la/s factura/s' Instruction.Glyph.Data = { 0A54504E474F626A65637489504E470D0A1A0A0000000D494844520000001C00 00001C0806000000720DDF940000000970485973000017120000171201679FD2 @@ -64,14 +64,16 @@ object dmGenerarFacturasProv: TdmGenerarFacturasProv 1FB8A1B4FF4FE32FF6FADB8B5E0000000049454E44AE426082} Instruction.Icon = tdiCustom CustomButtons = < - item - Caption = 'Ver el albar'#225'n' - Value = 100 - end item Caption = 'Continuar' Value = 200 Cancel = True + end + item + Caption = 'Ver factura' + Value = 100 + Info.Strings = ( + 'Mostrar la factura que se ha generado') end> ButtonBar.Buttons = [] ButtonBar.Cancel = cbOK diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.pas b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.pas index fc04178..4696b5d 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.pas +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvPedProvUtils.pas @@ -3,7 +3,7 @@ unit uGenerarFacturasProvPedProvUtils; interface uses - Windows, SysUtils, Classes, uBizPedidosProveedor, pngimage, JSDialog; + Windows, SysUtils, Classes, uBizPedidosProveedor, uBizFacturasProveedor, pngimage, JSDialog; type TdmGenerarFacturasProv = class(TDataModule) @@ -11,127 +11,108 @@ type end; function GenerarFacturaProv(const IDPedido : Integer) : Boolean; overload; - function GenerarFacturaProv(APedidos : IBizPedidoProveedor) : Boolean; overload; - function GenerarFacturaProv : Boolean; overload; + function GenerarFacturasProv : Boolean; overload; + function GenerarFacturasProv(APedidos : IBizPedidoProveedor) : Boolean; overload; + function GenerarFacturasdeListaPedidos(AFacturas: IBizFacturaProveedor; AListaPedidos: IBizPedidoProveedor): Boolean; implementation {$R *.dfm} uses - uDialogUtils, - uBizDetallesPedidoProveedor, + uDialogUtils, uControllerDetallesBase, DB, uDADataTable, schFacturasProveedorClient_Intf, + uBizDetallesPedidoProveedor, schPedidosProveedorClient_Intf, uPedidosProveedorController, uDetallesPedidoProveedorController, - uFacturasProveedorController, uBizFacturasProveedor, uBizDetallesFacturaProveedor; - -// , -// , uProveedoresController, -// , uControllerDetallesBase, - - -// , uBizContactos, schPedidosClienteClient_Intf, -// schPedidosProveedorClient_Intf; + uFacturasProveedorController, uBizDetallesFacturaProveedor; var dmGenerarFacturasProv: TdmGenerarFacturasProv; APedidosProveedorController : IPedidosProveedorController; ADetallesPedidosProveedorController : IDetallesPedidoProveedorController; AFacturasProveedorController : IFacturasProveedorController; -// AProveedoresController : IProveedoresController; { Métodos auxiliares } -{procedure CopiarPedidoAPedido(APedido: IBizPedidoCliente; - APedido : IBizFacturaProveedor); +procedure CopiarPedidoAFactura(APedido: IBizPedidoProveedor; AFactura : IBizFacturaProveedor); begin - if not Assigned(APedido) then - raise Exception.Create ('Albarán no asignado (CopiarPedidoAPedido)'); + if not Assigned(AFactura) then + raise Exception.Create ('Albarán no asignado (CopiarPedidoAAlbaran)'); if not Assigned(APedido) then - raise Exception.Create ('Pedido no asignado (CopiarPedidoAPedido)'); + raise Exception.Create ('Pedido no asignado (CopiarPedidoAAlbaran)'); if not APedido.DataTable.Active then APedido.DataTable.Active := True; - // El albarán tiene que venir ya abierto y posicionado donde hay que copiar - APedido.ID_CLIENTE := APedido.ID_CLIENTE; - APedido.ID_PEDIDO := APedido.ID; - APedido.CALLE := APedido.CALLE; - APedido.CODIGO_POSTAL := APedido.CODIGO_POSTAL; - APedido.POBLACION := APedido.POBLACION; - APedido.PROVINCIA := APedido.PROVINCIA; - APedido.PERSONA_CONTACTO := APedido.PERSONA_CONTACTO; - APedido.TELEFONO := APedido.TELEFONO; - APedido.IMPORTE_NETO := APedido.IMPORTE_NETO; - APedido.IMPORTE_PORTE := APedido.IMPORTE_PORTE; - APedido.DESCUENTO := APedido.DESCUENTO; - APedido.IMPORTE_DESCUENTO := APedido.IMPORTE_DESCUENTO; - APedido.BASE_IMPONIBLE := APedido.BASE_IMPONIBLE; - APedido.IVA := APedido.IVA; - APedido.IMPORTE_IVA := APedido.IMPORTE_IVA; - APedido.IMPORTE_TOTAL := APedido.IMPORTE_TOTAL; - APedido.DataTable.FieldByName(fld_PedidosClienteOBSERVACIONES).AsVariant := APedido.DataTable.FieldByName(fld_PedidosClienteOBSERVACIONES).AsVariant; - APedido.ID_FORMA_PAGO := APedido.ID_FORMA_PAGO; + APedidosProveedorController.RecuperarProveedor(APedido); + if not APedido.Proveedor.DataTable.Active then + APedido.Proveedor.DataTable.active := true; + + // La factura tiene que venir ya abierta y posicionado donde hay que copiar + AFactura.ID_PROVEEDOR := APedido.ID_PROVEEDOR; + AFactura.CALLE := APedido.CALLE; + AFactura.CODIGO_POSTAL := APedido.CODIGO_POSTAL; + AFactura.POBLACION := APedido.POBLACION; + AFactura.PROVINCIA := APedido.PROVINCIA; + AFactura.IMPORTE_NETO := APedido.IMPORTE_NETO; + AFactura.IMPORTE_PORTE := APedido.IMPORTE_PORTE; + AFactura.DESCUENTO := APedido.DESCUENTO; + AFactura.IMPORTE_DESCUENTO := APedido.IMPORTE_DESCUENTO; + AFactura.BASE_IMPONIBLE := APedido.BASE_IMPONIBLE; + AFactura.IVA := APedido.IVA; + AFactura.IMPORTE_IVA := APedido.IMPORTE_IVA; + AFactura.IMPORTE_TOTAL := APedido.IMPORTE_TOTAL; + AFactura.DataTable.FieldByName(fld_FacturasProveedorOBSERVACIONES).AsVariant := APedido.DataTable.FieldByName(fld_PedidosProveedorOBSERVACIONES).AsVariant; + AFactura.NIF_CIF := APedido.Proveedor.NIF_CIF; + AFactura.NOMBRE_COMERCIAL_PROVEEDOR := APedido.Proveedor.NOMBRE_COMERCIAL; + AFactura.ID_FORMA_PAGO := APedido.Proveedor.ID_FORMA_PAGO; end; -procedure CopiarArticulosPendAPedido( - APedido: IBizPedidoCliente; - APedido: IBizFacturaProveedor; - AArticulosPendientes: IBizPedidoClienteArticulosPend); +procedure CopiarArticulosAFactura(APedido: IBizPedidoProveedor; AFactura: IBizFacturaProveedor); var i : integer; ADetalles : IBizDetallesFacturaProveedor; - ADetallesController : IDetallesFacturaProveedorController; + begin - if not Assigned(APedido) then - raise Exception.Create ('Albarán no asignado (CopiarArticulosPendAPedido)'); + if not Assigned(AFactura) then + raise Exception.Create ('Factura no asignada (CopiarArticulosAFactura)'); if not Assigned(APedido) then - raise Exception.Create ('Pedido no asignado (CopiarArticulosPendAPedido)'); + raise Exception.Create ('Factura no asignada (CopiarArticulosAFactura)'); - if not Assigned(AArticulosPendientes) then - raise Exception.Create ('Artículos pendientes no asignado (CopiarArticulosPendAPedido)'); + // La factura tiene que venir ya abierta y posicionada donde hay que copiar - if not AArticulosPendientes.DataTable.Active then - AArticulosPendientes.DataTable.Active := True; - - // El albarán tiene que venir ya abierto y posicionado donde hay que copiar - - ADetalles := APedido.Detalles; - ADetallesController := TDetallesFacturaProveedorController.Create; + ADetalles := AFactura.Detalles; try //OJO IMPORTANTE //Siempre que vayamos a trabajar con los detalles debemos hacer un beginupdate de los mismos y un endupdate para //obligarle siempre a recalcular los detalles una sola vez - ADetallesController.BeginUpdate(ADetalles); + AFacturasProveedorController.DetallesController.BeginUpdate(ADetalles); + + APedido.Detalles.DataTable.First; + for i := 0 to APedido.Detalles.DataTable.RecordCount - 1 do + begin + AFacturasProveedorController.DetallesController.Add(ADetalles, TIPO_DETALLE_CONCEPTO); + ADetalles.Edit; + ADetalles.REFERENCIA := APedido.Detalles.REFERENCIA; + ADetalles.ID_ARTICULO := APedido.Detalles.ID_ARTICULO; + ADetalles.CONCEPTO := APedido.Detalles.CONCEPTO; + ADetalles.IMPORTE_UNIDAD := APedido.Detalles.IMPORTE_UNIDAD; + ADetalles.DESCUENTO := APedido.Detalles.DESCUENTO; + ADetalles.IMPORTE_PORTE := APedido.Detalles.IMPORTE_PORTE; + ADetalles.CANTIDAD := APedido.Detalles.CANTIDAD; + ADetalles.IMPORTE_TOTAL := APedido.Detalles.IMPORTE_TOTAL; + ADetalles.REFERENCIA_PROVEEDOR := APedido.Detalles.REFERENCIA_PROVEEDOR; + ADetalles.Post; + APedido.Detalles.Next; + end; - AArticulosPendientes.DataTable.First; - for i := 0 to AArticulosPendientes.DataTable.RecordCount - 1 do - begin - APedido.Detalles.First; - if (APedido.Detalles.Locate('ID_ARTICULO', AArticulosPendientes.ID_ARTICULO, [])) then - if (AArticulosPendientes.CANTIDAD_PENDIENTE > 0) then - begin - ADetallesController.Add(ADetalles, TIPO_DETALLE_CONCEPTO); - ADetalles.Edit; - ADetalles.REFERENCIA := APedido.Detalles.REFERENCIA; - ADetalles.ID_ARTICULO := APedido.Detalles.ID_ARTICULO; - ADetalles.CONCEPTO := APedido.Detalles.CONCEPTO; - ADetalles.CANTIDAD := AArticulosPendientes.CANTIDAD_PENDIENTE; - ADetalles.IMPORTE_UNIDAD := APedido.Detalles.IMPORTE_UNIDAD; - ADetalles.IMPORTE_TOTAL := APedido.Detalles.IMPORTE_TOTAL; - ADetalles.DESCUENTO := APedido.Detalles.DESCUENTO; - ADetalles.IMPORTE_PORTE := APedido.Detalles.IMPORTE_PORTE; - ADetalles.VISIBLE := APedido.Detalles.VISIBLE; - ADetalles.REFERENCIA_PROVEEDOR := APedido.Detalles.REFERENCIA_PROVEEDOR; - ADetalles.Post; - AArticulosPendientes.Next; - end; - end; finally - ADetallesController.EndUpdate(ADetalles); - ADetallesController := NIL; + AFacturasProveedorController.DetallesController.EndUpdate(ADetalles); +// AFacturasProveedorController.DetallesController.ActualizarTotales(ADetalles); end; -end; } +end; + + procedure Inicializar; begin @@ -161,74 +142,212 @@ begin Inicializar; APedido := APedidosProveedorController.Buscar(IDPedido); - Result := GenerarFacturaProv(APedido); + Result := GenerarFacturasProv(APedido); if Assigned(APedidosProveedorController) then Finalizar; end; -function GenerarFacturaProv(APedidos : IBizPedidoProveedor) : Boolean; overload; -var - ARespuesta : Integer; - AFacturasNuevas : IBizFacturaProveedor; -// AArticulos: IBizPedidoClienteArticulosPend; - i: Integer; -begin - Result := False; - if not Assigned(APedidosProveedorController) then - Inicializar; - - if not Assigned(APedidos) then - raise Exception.Create('Albarán de proveedor no asignado (GenerarFacturaProv)'); - - if not APedidos.DataTable.Active then - APedidos.DataTable.Active := True; - - try - AFacturasNuevas := AFacturasProveedorController.Nuevo(False); - if AFacturasProveedorController.Anadir(AFacturasNuevas, APedidos.ID) then - begin - if AFacturasNuevas.DataTable.RecordCount = 1 then - AFacturasProveedorController.Ver(AFacturasNuevas) - else begin - with dmGenerarFacturasProv.JsListaFacturasGeneradas.Content do - begin - Clear; - AFacturasNuevas.DataTable.Last; - for i := 0 to AFacturasNuevas.DataTable.RecordCount - 1 do - begin - if Length(AFacturasNuevas.REFERENCIA) > 0 then - Add(AFacturasNuevas.REFERENCIA + ': ' + AFacturasNuevas.NOMBRE); - AFacturasNuevas.DataTable.Prior; - end; - end; - dmGenerarFacturasProv.JsListaFacturasGeneradas.Execute; - end; -// actRefrescar.Execute; - end; - finally - AFacturasNuevas := NIL; - end; -end; - -function GenerarFacturaProv : Boolean; overload; +function GenerarFacturasProv : Boolean; overload; var APedidos : IBizPedidoProveedor; begin -{ Result := False; if not Assigned(APedidosProveedorController) then Inicializar; APedidos := APedidosProveedorController.ElegirPedidos(APedidosProveedorController.BuscarSinFacturar, - 'Elija el albarán o Pedidos de proveedor que desea utilizar para dar de alta la factura.' + 'Elija el pedido/s de proveedor que desea utilizar para dar de alta la factura.' + #10#13 + 'Si elige Pedidos de proveedores diferentes se dará de alta una factura por cada uno de ellos.' , True); - Result := GenerarFacturaProv(APedidos); + if Assigned(APedidos) then + Result := GenerarFacturasProv(APedidos); if Assigned(APedidosProveedorController) then Finalizar; -} +end; + +function GenerarFacturasProv(APedidos : IBizPedidoProveedor) : Boolean; overload; +var + AFacturasNuevas : IBizFacturaProveedor; + i: Integer; + ARespuesta : Integer; + +begin + Result := False; + + if not Assigned(APedidosProveedorController) then + Inicializar; + + if not Assigned(APedidos) then + raise Exception.Create('Pedidos de proveedor no asignado (GenerarFacturasProv)'); + + if not APedidos.DataTable.Active then + APedidos.DataTable.Active := True; + + try + AFacturasNuevas := AFacturasProveedorController.Nuevo(False); + if GenerarFacturasdeListaPedidos(AFacturasNuevas, APedidos) then + begin + if AFacturasNuevas.DataTable.RecordCount = 1 then + begin + with dmGenerarFacturasProv.JsListaFacturasGeneradas do + begin + Content.Clear; + Content.Add(Format('Se ha generado correctamente la factura %s a partir del pedido de proveedor' + #10#13, [AFacturasNuevas.REFERENCIA])); + end; + end + else begin + dmGenerarFacturasProv.JsListaFacturasGeneradas.CustomButtons[1].Destroy; + with dmGenerarFacturasProv.JsListaFacturasGeneradas.Content do + begin + Clear; + AFacturasNuevas.DataTable.Last; + for i := 0 to AFacturasNuevas.DataTable.RecordCount - 1 do + begin + if Length(AFacturasNuevas.REFERENCIA) > 0 then + Add(AFacturasNuevas.REFERENCIA + ': ' + AFacturasNuevas.NOMBRE); + AFacturasNuevas.DataTable.Prior; + end; + end; + end; + + dmGenerarFacturasProv.JsListaFacturasGeneradas.Execute; + ARespuesta := dmGenerarFacturasProv.JsListaFacturasGeneradas.CustomButtonResult; + case ARespuesta of + 100 : begin + // Ver la factura + AFacturasProveedorController.Ver(AFacturasNuevas); + end; + 200 : // Continuar; + end; + end; + + finally + AFacturasNuevas := NIL; + end; +end; + +function GenerarFacturasdeListaPedidos(AFacturas: IBizFacturaProveedor; AListaPedidos: IBizPedidoProveedor): Boolean; +var + AFacturaActual : IBizFacturaProveedor; + APedidosController : IPedidosProveedorController; + AArticulosPendientes : IBizDetallesPedidoProveedorPend; + I: Integer; + bEnEdicion : Boolean; +begin + Result := False; + + // ATENCIÓN!!! AFacturas tiene que estar vacio para no pisar facturas + // ya generados. + if not Assigned(AFacturas) then + raise Exception.Create ('Facturas no asignado (Anadir)'); + + if not Assigned(AListaPedidos) then + raise Exception.Create ('Pedidos no asignados (Anadir)'); + + if not AFacturas.DataTable.Active then + AFacturas.DataTable.Active := True; + + if not AListaPedidos.DataTable.Active then + AListaPedidos.DataTable.Active := True; + + APedidosController := TPedidosProveedorController.Create; + try + // Ordenar por fecha de pedido + AListaPedidos.DataTable.Sort([fld_PedidosProveedorFECHA_PEDIDO], [uDADataTable.sdAscending]); + AListaPedidos.First; + for I := 0 to AListaPedidos.DataTable.RecordCount - 1 do + begin + AListaPedidos._Proveedor := NIL; + AFacturaActual := NIL; + + // Busco si hay alguna factura ya hecha de ese Proveedor + AFacturas.DataTable.First; + if AFacturas.DataTable.Locate(fld_FacturasProveedorID_Proveedor, AListaPedidos.ID_Proveedor, []) then + AFacturaActual := AFacturas + else + begin + // No hay factura de ese proveedor. Creo una nueva + AFacturasProveedorController.Anadir(AFacturas); + AFacturaActual := AFacturas; + end; + + //Asignamos el proveedor del pedido en la factura siempre + APedidosController.RecuperarProveedor(AListaPedidos); + AFacturaActual.Proveedor := AListaPedidos.Proveedor; + + //Tanto si es nueva como ya existe añadimos la referencia del pedido a añadir + bEnEdicion := (AFacturaActual.DataTable.State in dsEditModes); + if not bEnEdicion then + AFacturaActual.Edit; + //Por cada pedido a añadir lo asignamos al campo manual de referencias de pedidos asociados REF_PEDIDOS_PROV + AFacturaActual.REF_PEDIDOS_PROV := AFacturaActual.REF_PEDIDOS_PROV + ' ' + AListaPedidos.REFERENCIA; + AFacturaActual.Post; + if bEnEdicion then + AFacturaActual.Edit; + + + AFacturaActual.Detalles.DataTable.Last; + // Añado el título + AFacturasProveedorController.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_TITULO); + with AFacturaActual.Detalles do + begin + Edit; + CONCEPTO := 'Pedido ' + AListaPedidos.REFERENCIA + ' del ' + DateToStr(AListaPedidos.FECHA_PEDIDO); + Post; + end; + + // Añado el contenido del pedido + CopiarArticulosAFactura(AListaPedidos, AFacturaActual); + +{En los albaranes a proveedor el porte es a nivel del artículo + Self.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_CONCEPTO); + with AFacturaActual.Detalles do + begin + Edit; + CONCEPTO := 'Porte del albarán'; + CANTIDAD := 1; + IMPORTE_UNIDAD := AListaAlbaranes.IMPORTE_PORTE; + Post; + end; +} + + // Añado el resumen + AFacturasProveedorController.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_SUBTOTAL); + with AFacturaActual.Detalles do + begin + Edit; + CONCEPTO := 'Total del pedido ' + AListaPedidos.REFERENCIA; + Post; + end; + + // Añado una línea en blanco + AFacturasProveedorController.DetallesController.Add(AFacturaActual.Detalles, TIPO_DETALLE_CONCEPTO); + with AFacturaActual.Detalles do + begin + Edit; + CONCEPTO := ''; + Post; + end; + + // Guardo el albaran que acabo de generar o editar + AFacturaActual.CalcularImporteTotal; + AFacturasProveedorController.Guardar(AFacturaActual); + // No se asocia la factura al pedido ya que un pedido, solo puede estar asociado a una factura y una factura puede tener asociados varios pedidos + //09/06/2025 ahora Stefy nos dice que puede venir un pedido en varias facturas diferentes por lo que no podemos asociar la factura al pedido + AListaPedidos.Edit; + AListaPedidos.ID_FACTURA := AFacturaActual.ID; + AListaPedidos.REF_FACTURA := AFacturaActual.REFERENCIA; + AListaPedidos.Post; + APedidosController.Guardar(AListaPedidos); + + AListaPedidos.Next; + end; + Result := True; + finally + APedidosController := NIL; + end; end; end. diff --git a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvUtils.pas b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvUtils.pas index a18a3c1..782bb0d 100644 --- a/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvUtils.pas +++ b/Source/Modulos/Relaciones/Pedidos de proveedor - Facturas de proveedor/uGenerarFacturasProvUtils.pas @@ -10,9 +10,9 @@ type JsListaFacturasGeneradas: TJSDialog; end; - function GenerarFacturaProv(const IDAlbaran : Integer) : Boolean; overload; - function GenerarFacturaProv(AAlbaranes : IBizAlbaranProveedor) : Boolean; overload; - function GenerarFacturaProv : Boolean; overload; +// function GenerarFacturaProv(const IDAlbaran : Integer) : Boolean; overload; +// function GenerarFacturaProv(AAlbaranes : IBizAlbaranProveedor) : Boolean; overload; +// function GenerarFacturaProv : Boolean; overload; implementation @@ -152,7 +152,7 @@ begin end; -function GenerarFacturaProv(const IDAlbaran : Integer) : Boolean; overload; +{function GenerarFacturaProv(const IDAlbaran : Integer) : Boolean; overload; var AAlbaran : IBizAlbaranProveedor; begin @@ -227,6 +227,6 @@ begin if Assigned(AAlbaranesProveedorController) then Finalizar; -end; +end; } end. diff --git a/Source/Modulos/Subfamilias/Controller/View/uIEditorSubFamilias.pas b/Source/Modulos/Subfamilias/Controller/View/uIEditorSubFamilias.pas index f01b68f..fe503e5 100644 --- a/Source/Modulos/Subfamilias/Controller/View/uIEditorSubFamilias.pas +++ b/Source/Modulos/Subfamilias/Controller/View/uIEditorSubFamilias.pas @@ -3,11 +3,14 @@ unit uIEditorSubFamilias; interface uses - uEditorDBBase, uBizSubFamilias, uSubFamiliasController; + uEditorDBBase, uBizSubFamilias, uSubFamiliasController, uGUIBase; type - IEditorSubFamilias = interface(IEditorDBBase) + IEditorSubFamilias = interface(ICustomEditor) ['{F4D0EEEA-D5D4-488E-B495-33ADA54135BF}'] + function ShowModal : Integer; + procedure Show; + function GetSubFamilias: IBizSubFamilia; procedure SetSubFamilias(const Value: IBizSubFamilia); property SubFamilias: IBizSubFamilia read GetSubFamilias write SetSubFamilias; diff --git a/Source/Modulos/Tarifas/Controller/Tarifas_controller.dproj b/Source/Modulos/Tarifas/Controller/Tarifas_controller.dproj index 574bf6c..dafdd6f 100644 --- a/Source/Modulos/Tarifas/Controller/Tarifas_controller.dproj +++ b/Source/Modulos/Tarifas/Controller/Tarifas_controller.dproj @@ -47,16 +47,16 @@ MainSource + + + + + + + - - - - - - -