2007-06-11 15:29:06 +00:00
unit uGenerarAlbaranesCliUtils;
interface
uses
2008-04-21 07:35:55 +00:00
Windows, SysUtils, Classes, pngimage, JSDialog, uBizContactos,
uBizPedidosCliente, uBizAlbaranesCliente, uBizInventario;
2007-06-11 15:29:06 +00:00
type
TdmGenerarAlbaranesCli = class( TDataModule)
JsListaAlbaranesGenerados: TJSDialog;
end ;
2007-06-14 13:10:45 +00:00
function GenerarAlbaranCli( const IDPedido : Integer ; var IDAlbaran: Integer ) : Boolean ; overload ;
function GenerarAlbaranCli( APedido : IBizPedidoCliente; var AAlbaran: IBizAlbaranCliente) : Boolean ; overload ;
function ElegirPedidoYGenerarAlbaranCli( var IDAlbaran: Integer ) : Boolean ;
2007-06-11 15:29:06 +00:00
2008-04-21 07:35:55 +00:00
//Metodos para albaranar articulos pendientes
2008-05-29 13:58:49 +00:00
function GenerarAlbaranesCli( AArticulos : IBizDetalleSinAlbaran; var AAlbaranes: IBizAlbaranCliente; const IDAlmacen: Integer ) : Boolean ; overload ;
procedure InicializarAlbaran( var AAlbaranes: IBizAlbaranCliente; ACliente: IBizCliente; const IDAlmacen: Integer ; AArticulos: IBizDetalleSinAlbaran) ;
2008-04-21 07:35:55 +00:00
2007-06-11 15:29:06 +00:00
implementation
{$R *.dfm}
uses
2008-04-21 07:35:55 +00:00
cxControls, uDialogUtils, uBizDetallesPedidoCliente, uBizDetallesAlbaranCliente,
2007-06-14 13:10:45 +00:00
uPedidosClienteController, uAlbaranesClienteController, uClientesController,
2007-06-11 15:29:06 +00:00
uDetallesAlbaranClienteController, uControllerDetallesBase,
2008-04-21 07:35:55 +00:00
schPedidosClienteClient_Intf, uDADataTable,
schAlbaranesClienteClient_Intf, schInventarioClient_Intf;
2007-06-11 15:29:06 +00:00
var
dmGenerarAlbaranesCli: TdmGenerarAlbaranesCli;
APedidosClienteController : IPedidosClienteController;
AAlbaranesClienteController : IAlbaranesClienteController;
ADetallesAlbaranesCliController : IDetallesAlbaranClienteController;
AClientesController : IClientesController;
{ M<> todos auxiliares }
procedure CopiarPedidoAAlbaran( APedido: IBizPedidoCliente;
AAlbaran : IBizAlbaranCliente) ;
begin
if not Assigned( AAlbaran) then
raise Exception. Create ( 'Albar<61> n no asignado (CopiarPedidoAAlbaran)' ) ;
if not Assigned( APedido) then
raise Exception. Create ( 'Pedido no asignado (CopiarPedidoAAlbaran)' ) ;
if not APedido. DataTable. Active then
APedido. DataTable. Active : = True ;
// El albar<61> n tiene que venir ya abierto y posicionado donde hay que copiar
AAlbaran. ID_CLIENTE : = APedido. ID_CLIENTE;
AAlbaran. ID_PEDIDO : = APedido. ID;
2008-03-28 15:10:28 +00:00
AAlbaran. TIPO : = CTE_TIPO_ALBARAN;
2007-08-29 17:16:09 +00:00
AAlbaran. REFERENCIA_CLIENTE : = APedido. REFERENCIA_CLIENTE;
2007-06-11 15:29:06 +00:00
AAlbaran. CALLE : = APedido. CALLE;
AAlbaran. CODIGO_POSTAL : = APedido. CODIGO_POSTAL;
AAlbaran. POBLACION : = APedido. POBLACION;
AAlbaran. PROVINCIA : = APedido. PROVINCIA;
AAlbaran. PERSONA_CONTACTO : = APedido. PERSONA_CONTACTO;
AAlbaran. TELEFONO : = APedido. TELEFONO;
AAlbaran. IMPORTE_NETO : = APedido. IMPORTE_NETO;
AAlbaran. IMPORTE_PORTE : = APedido. IMPORTE_PORTE;
AAlbaran. DESCUENTO : = APedido. DESCUENTO;
AAlbaran. IMPORTE_DESCUENTO : = APedido. IMPORTE_DESCUENTO;
AAlbaran. BASE_IMPONIBLE : = APedido. BASE_IMPONIBLE;
AAlbaran. IVA : = APedido. IVA;
AAlbaran. IMPORTE_IVA : = APedido. IMPORTE_IVA;
AAlbaran. IMPORTE_TOTAL : = APedido. IMPORTE_TOTAL;
AAlbaran. DataTable. FieldByName( fld_AlbaranesClienteOBSERVACIONES) . AsVariant : = APedido. DataTable. FieldByName( fld_PedidosClienteOBSERVACIONES) . AsVariant;
AAlbaran. ID_FORMA_PAGO : = APedido. ID_FORMA_PAGO;
AAlbaran. FECHA_PREVISTA_ENVIO : = APedido. FECHA_PREVISTA_ENVIO;
end ;
procedure CopiarArticulosPendAAlbaran(
APedido: IBizPedidoCliente;
AAlbaran: IBizAlbaranCliente;
AArticulosPendientes: IBizPedidoClienteArticulosPend) ;
var
i : integer ;
ADetalles : IBizDetallesAlbaranCliente;
ADetallesController : IDetallesAlbaranClienteController;
begin
if not Assigned( AAlbaran) then
raise Exception. Create ( 'Albar<61> n no asignado (CopiarArticulosPendAAlbaran)' ) ;
if not Assigned( APedido) then
raise Exception. Create ( 'Pedido no asignado (CopiarArticulosPendAAlbaran)' ) ;
if not Assigned( AArticulosPendientes) then
raise Exception. Create ( 'Art<72> culos pendientes no asignado (CopiarArticulosPendAAlbaran)' ) ;
if not AArticulosPendientes. DataTable. Active then
AArticulosPendientes. DataTable. Active : = True ;
// El albar<61> n tiene que venir ya abierto y posicionado donde hay que copiar
ADetalles : = AAlbaran. Detalles;
ADetallesController : = TDetallesAlbaranClienteController. Create;
try
2008-05-26 14:11:46 +00:00
//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) ;
2007-06-11 15:29:06 +00:00
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;
2008-03-28 15:10:28 +00:00
ADetalles. ID_PEDIDO : = APedido. Detalles. ID_PEDIDO;
2007-06-11 15:29:06 +00:00
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
2008-05-26 14:11:46 +00:00
ADetallesController. EndUpdate( ADetalles) ;
2007-06-11 15:29:06 +00:00
ADetallesController : = NIL ;
end ;
end ;
2008-04-21 07:35:55 +00:00
2007-06-11 15:29:06 +00:00
procedure Inicializar;
begin
dmGenerarAlbaranesCli : = TdmGenerarAlbaranesCli. Create( nil ) ;
APedidosClienteController : = TPedidosClienteController. Create;
AAlbaranesClienteController : = TAlbaranesClienteController. Create;
ADetallesAlbaranesCliController : = TDetallesAlbaranClienteController. Create;
AClientesController : = TClientesController. Create;
end ;
procedure Finalizar;
begin
FreeAndNIL( dmGenerarAlbaranesCli) ;
APedidosClienteController : = nil ;
AAlbaranesClienteController : = nil ;
ADetallesAlbaranesCliController : = nil ;
AClientesController : = nil ;
end ;
2007-06-14 13:10:45 +00:00
function GenerarAlbaranCli( const IDPedido : Integer ;
var IDAlbaran: Integer ) : Boolean ; overload ;
2007-06-11 15:29:06 +00:00
var
APedido : IBizPedidoCliente;
2007-06-14 13:10:45 +00:00
AAlbaran : IBizAlbaranCliente;
2007-06-11 15:29:06 +00:00
begin
Result : = False ;
2007-06-14 13:10:45 +00:00
IDAlbaran : = - 1 ;
2008-04-21 07:35:55 +00:00
2007-06-11 15:29:06 +00:00
try
if not Assigned( APedidosClienteController) then
Inicializar;
APedido : = APedidosClienteController. Buscar( IDPedido) ;
if Assigned( APedido) then
2007-06-14 13:10:45 +00:00
begin
Result : = GenerarAlbaranCli( APedido, AAlbaran) ;
if Result then
IDAlbaran : = AAlbaran. ID;
end ;
2007-06-11 15:29:06 +00:00
finally
if Assigned( APedidosClienteController) then
Finalizar;
end ;
end ;
2007-06-14 13:10:45 +00:00
function GenerarAlbaranCli( APedido : IBizPedidoCliente; var AAlbaran: IBizAlbaranCliente) : Boolean ; overload ;
2007-06-11 15:29:06 +00:00
var
ARespuesta : Integer ;
2007-06-14 13:10:45 +00:00
AuxAlbaran : IBizAlbaranCliente;
2007-06-11 15:29:06 +00:00
AArticulosPendientes: IBizPedidoClienteArticulosPend;
begin
Result : = False ;
2007-06-14 13:10:45 +00:00
AAlbaran : = NIL ;
2007-06-11 15:29:06 +00:00
if not Assigned( APedido) then
raise Exception. Create( 'Pedido de cliente no asignado (GenerarAlbaranCli)' ) ;
if not APedido. DataTable. Active then
APedido. DataTable. Active : = True ;
if not Assigned( APedidosClienteController) then
Inicializar;
try
AArticulosPendientes : = APedidosClienteController. ArticulosPendientes( APedido. ID) ;
if not Assigned( AArticulosPendientes) then
raise Exception. Create( 'Error al recuperar los art<72> culos sin albar<61> n del pedido (GenerarAlbaranCli)' ) ;
AArticulosPendientes. DataTable. Active : = True ;
if AArticulosPendientes. DataTable. RecordCount = 0 then
begin
ShowWarningMessage( 'Generar albar<61> n a partir del pedido' , 'Todos los art<72> culos de este pedido ya figuran en uno o m<> s albaranes de cliente. Por lo que no se pueden generar nuevos albaranes para este pedido' ) ;
Exit; // Aunque es un exit, se ejecuta la parte del finally antes de salir.
end ;
2007-06-14 13:10:45 +00:00
AuxAlbaran : = AAlbaranesClienteController. Nuevo;
CopiarPedidoAAlbaran( APedido, AuxAlbaran) ;
CopiarArticulosPendAAlbaran( APedido, AuxAlbaran, AArticulosPendientes) ;
2007-06-11 15:29:06 +00:00
//Sustituir por if de guardar
2007-06-14 13:10:45 +00:00
if AAlbaranesClienteController. Guardar( AuxAlbaran) then
2007-06-11 15:29:06 +00:00
begin
2007-06-14 13:10:45 +00:00
AAlbaran : = AuxAlbaran;
2007-06-11 15:29:06 +00:00
with dmGenerarAlbaranesCli. JsListaAlbaranesGenerados do
begin
Instruction. Text : = 'Se ha generado el albar<61> n' ;
Content. Clear;
2007-06-14 13:10:45 +00:00
Content. Add( Format( 'Se ha generado correctamente el albar<61> n %s a partir del pedido de cliente' + #10 #13 , [ AuxAlbaran. REFERENCIA] ) ) ;
2007-06-11 15:29:06 +00:00
Execute;
ARespuesta : = CustomButtonResult;
case ARespuesta of
1 0 0 : begin
// Ver el albar<61> n
2007-06-14 13:10:45 +00:00
AAlbaranesClienteController. Ver( AuxAlbaran) ;
2007-06-11 15:29:06 +00:00
end ;
2 0 0 : // Continuar;
end ;
end ;
end ;
Result : = True ;
finally
AArticulosPendientes : = NIL ;
if Assigned( APedidosClienteController) then
Finalizar;
end ;
end ;
2007-06-14 13:10:45 +00:00
function ElegirPedidoYGenerarAlbaranCli( var IDAlbaran: Integer ) : Boolean ; overload ;
2007-06-11 15:29:06 +00:00
var
APedido : IBizPedidoCliente;
2007-06-14 13:10:45 +00:00
AAlbaran : IBizAlbaranCliente;
2007-06-11 15:29:06 +00:00
begin
Result : = False ;
2007-06-14 13:10:45 +00:00
IDAlbaran : = - 1 ;
AAlbaran : = NIL ;
2007-06-11 15:29:06 +00:00
try
if not Assigned( APedidosClienteController) then
2007-06-14 13:10:45 +00:00
Inicializar;
2007-06-11 15:29:06 +00:00
APedido : = APedidosClienteController. ElegirPedidos( APedidosClienteController. BuscarPendientes,
'Elija el pedido de cliente que desea utilizar para dar de alta el albar<61> n de cliente.'
, False ) ;
if Assigned( APedido) then
2007-06-14 13:10:45 +00:00
begin
Result : = GenerarAlbaranCli( APedido, AAlbaran) ;
if Result then
IDAlbaran : = AAlbaran. ID;
end ;
2007-06-11 15:29:06 +00:00
finally
if Assigned( APedidosClienteController) then
2007-06-14 13:10:45 +00:00
Finalizar;
2007-06-11 15:29:06 +00:00
end ;
end ;
2008-05-29 13:58:49 +00:00
function GenerarAlbaranesCli( AArticulos : IBizDetalleSinAlbaran; var AAlbaranes: IBizAlbaranCliente; const IDAlmacen: Integer ) : Boolean ; overload ;
2008-04-21 07:35:55 +00:00
var
ARespuesta : Integer ;
ACliente: IBizCliente;
RefPedCliAux: String ;
I: Integer ;
begin
Result : = False ;
if not Assigned( AArticulos) then
raise Exception. Create( 'AArticulos no asignado (GenerarAlbaranesCli)' ) ;
if not Assigned( APedidosClienteController) then
Inicializar;
ShowHourglassCursor;
try
//Preparamos el componente donde almacenaremos las referencias de los albaranes generados
dmGenerarAlbaranesCli. JsListaAlbaranesGenerados. CustomButtons. Clear;
dmGenerarAlbaranesCli. JsListaAlbaranesGenerados. Content. Clear;
dmGenerarAlbaranesCli. JsListaAlbaranesGenerados. Instruction. Text : = 'Se han generado los albaranes' ;
// Ordenar por cliente y pedido
AArticulos. DataTable. Sort( [ fld_AlbaranesClienteID_CLIENTE, fld_AlbaranesClienteID_PEDIDO] , [ uDADataTable. sdAscending, uDADataTable. sdAscending] ) ;
AArticulos. DataTable. First;
//Inicializamos albaran
ACliente : = ( AClientesController. Buscar( AArticulos. ID_CLIENTE) as IBizCliente) ;
ACliente. DataTable. Active : = True ;
AAlbaranes : = AAlbaranesClienteController. Nuevo;
2008-05-29 13:58:49 +00:00
InicializarAlbaran( AAlbaranes, ACliente, IDAlmacen, AArticulos) ;
2008-04-21 07:35:55 +00:00
2008-05-26 14:11:46 +00:00
//Aqui no es necesario BeginUpdate y EndUpdate de los detalles porque siempre a<> adimos una linea al final.
2008-04-21 07:35:55 +00:00
// A<> ado el t<> tulo del pedido ya que siempre tendremos al menos un concepto de pedido
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_TITULO) ;
with AAlbaranes. Detalles do
begin
Edit;
RefPedCliAux : = AArticulos. REFERENCIA_PEDIDO;
CONCEPTO : = 'Pedido ' + AArticulos. REFERENCIA_PEDIDO + ' (Ref.Cliente: ' + AArticulos. REFERENCIA_CLI_PEDIDO + ') del ' + DateToStr( AArticulos. FECHA_PEDIDO) ;
Post;
end ;
for I : = 0 to AArticulos. DataTable. RecordCount - 1 do
begin
//En el caso que se cambie de pedido, cerramos detalles del pedido
if ( RefPedCliAux < > AArticulos. REFERENCIA_PEDIDO) then
begin
// A<> ado el resumen del pedido
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_SUBTOTAL) ;
with AAlbaranes. Detalles do
begin
Edit;
CONCEPTO : = 'Total del pedido ' + RefPedCliAux;
Post;
end ;
// A<> ado una l<> nea en blanco
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_CONCEPTO) ;
with AAlbaranes. Detalles do
begin
Edit;
CONCEPTO : = '' ;
Post;
end ;
//En el caso que cambie de pedido pero no de cliente volvemos a crear la cabecera del nuevo pedido
if ( ACliente. ID = AArticulos. ID_CLIENTE) then
begin
// A<> ado el t<> tulo del pedido ya que siempre tendremos al menos un concepto de pedido
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_TITULO) ;
with AAlbaranes. Detalles do
begin
Edit;
RefPedCliAux : = AArticulos. REFERENCIA_PEDIDO;
CONCEPTO : = 'Pedido ' + AArticulos. REFERENCIA_PEDIDO + ' (Ref.Cliente: ' + AArticulos. REFERENCIA_CLI_PEDIDO + ') del ' + DateToStr( AArticulos. FECHA_PEDIDO) ;
Post;
end ;
end ;
end ;
//En el caso que cambie el cliente se guarda el albaran actual y se crea uno nuevo
if ( ACliente. ID < > AArticulos. ID_CLIENTE) then
begin
AAlbaranesClienteController. RecalcularImportes( AAlbaranes) ;
AAlbaranesClienteController. Guardar( AAlbaranes) ;
dmGenerarAlbaranesCli. JsListaAlbaranesGenerados. Content. Add( Format( '%s: %s' + #10 #13 , [ AAlbaranes. REFERENCIA, ACliente. NOMBRE] ) ) ;
//Inicializamos albaran
ACliente : = ( AClientesController. Buscar( AArticulos. ID_CLIENTE) as IBizCliente) ;
ACliente. DataTable. Active : = True ;
AAlbaranesClienteController. Anadir( AAlbaranes) ;
2008-05-29 13:58:49 +00:00
InicializarAlbaran( AAlbaranes, ACliente, IDAlmacen, AArticulos) ;
2008-04-21 07:35:55 +00:00
// A<> ado el t<> tulo del pedido ya que siempre tendremos al menos un concepto de pedido
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_TITULO) ;
with AAlbaranes. Detalles do
begin
Edit;
RefPedCliAux : = AArticulos. REFERENCIA_PEDIDO;
CONCEPTO : = 'Pedido ' + AArticulos. REFERENCIA_PEDIDO + ' (Ref.Cliente: ' + AArticulos. REFERENCIA_CLI_PEDIDO + ') del ' + DateToStr( AArticulos. FECHA_PEDIDO) ;
Post;
end ;
end ;
//Rellenamos el detalle del albar<61> n
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_CONCEPTO) ;
AAlbaranes. Detalles. Edit;
AAlbaranes. Detalles. ID_PEDIDO : = AArticulos. ID_PEDIDO;
AAlbaranes. Detalles. REFERENCIA : = AArticulos. REFERENCIA;
AAlbaranes. Detalles. REFERENCIA_PROVEEDOR : = AArticulos. REFERENCIA_PROVEEDOR;
AAlbaranes. Detalles. ID_ARTICULO : = AArticulos. ID_ARTICULO;
AAlbaranes. Detalles. CONCEPTO : = AArticulos. DESCRIPCION;
AAlbaranes. Detalles. CANTIDAD : = AArticulos. CANTIDAD_PENDIENTE;
AAlbaranes. Detalles. IMPORTE_UNIDAD : = AArticulos. PRECIO_COSTE;
AAlbaranes. Detalles. DESCUENTO : = AArticulos. DESCUENTO;
AAlbaranes. Detalles. Post;
//Pasamos al siguiente articulo
AArticulos. DataTable. Next;
end ;
//Finalmente cerraremos el <20> ltimo pedido del <20> ltimo albar<61> n
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_SUBTOTAL) ;
with AAlbaranes. Detalles do
begin
Edit;
CONCEPTO : = 'Total del pedido ' + RefPedCliAux;
Post;
end ;
// A<> ado una l<> nea en blanco
ADetallesAlbaranesCliController. Add( AAlbaranes. Detalles, TIPO_DETALLE_CONCEPTO) ;
with AAlbaranes. Detalles do
begin
Edit;
CONCEPTO : = '' ;
Post;
end ;
AAlbaranesClienteController. RecalcularImportes( AAlbaranes) ;
AAlbaranesClienteController. Guardar( AAlbaranes) ;
dmGenerarAlbaranesCli. JsListaAlbaranesGenerados. Content. Add( Format( '%s: %s' + #10 #13 , [ AAlbaranes. REFERENCIA, ACliente. NOMBRE] ) ) ;
finally
HideHourglassCursor;
//Visualizamos los albaranes generados
dmGenerarAlbaranesCli. JsListaAlbaranesGenerados. Execute;
if Assigned( APedidosClienteController) then
Finalizar;
end ;
end ;
2008-05-29 13:58:49 +00:00
procedure InicializarAlbaran( var AAlbaranes: IBizAlbaranCliente; ACliente: IBizCliente; const IDAlmacen: Integer ; AArticulos: IBizDetalleSinAlbaran) ;
2008-04-21 07:35:55 +00:00
begin
//El albaran debe venir abierto y posicionado para la copia.
AAlbaranes. Cliente : = ( ACliente as IBizCliente) ;
AAlbaranes. TIPO : = CTE_TIPO_ALBARAN;
2008-05-29 13:58:49 +00:00
AAlbaranes. ID_ALMACEN : = IDAlmacen;
2008-04-21 07:35:55 +00:00
AAlbaranes. REFERENCIA_CLIENTE : = AArticulos. REFERENCIA_CLI_PEDIDO;
AAlbaranes. FECHA_PREVISTA_ENVIO : = AArticulos. FECHA_PREVISTA_PEDIDO;
AAlbaranes. CALLE : = AArticulos. CALLE;
AAlbaranes. CODIGO_POSTAL : = AArticulos. CODIGO_POSTAL;
AAlbaranes. POBLACION : = AArticulos. POBLACION;
AAlbaranes. PROVINCIA : = AArticulos. PROVINCIA;
AAlbaranes. PERSONA_CONTACTO : = AArticulos. PERSONA_CONTACTO;
AAlbaranes. TELEFONO : = AArticulos. TELEFONO;
AAlbaranes. IVA : = AArticulos. IVA;
AAlbaranes. ID_FORMA_PAGO : = AArticulos. ID_FORMA_PAGO;
end ;
2007-06-11 15:29:06 +00:00
end .