PageRenderTime 60ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/facturacion_base/controller/ventas_factura.php

https://gitlab.com/cosouth.battle/sartinofi
PHP | 469 lines | 395 code | 49 blank | 25 comment | 52 complexity | aa6c1db97c95614643799cfbaec41780 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of Sartin
  4. * Miguel San Martin - cosouth.battle@gmail.com
  5. */
  6. require_model('agencia_transporte.php');
  7. require_model('articulo.php');
  8. require_model('asiento.php');
  9. require_model('asiento_factura.php');
  10. require_model('cliente.php');
  11. require_model('cuenta_banco_cliente.php');
  12. require_model('divisa.php');
  13. require_model('ejercicio.php');
  14. require_model('factura_cliente.php');
  15. require_model('forma_pago.php');
  16. require_model('pais.php');
  17. require_model('partida.php');
  18. require_model('serie.php');
  19. require_model('subcuenta.php');
  20. class ventas_factura extends fs_controller
  21. {
  22. public $agencia;
  23. public $agente;
  24. public $agentes;
  25. public $allow_delete;
  26. public $cliente;
  27. public $divisa;
  28. public $ejercicio;
  29. public $factura;
  30. public $forma_pago;
  31. public $mostrar_boton_pagada;
  32. public $pais;
  33. public $rectificada;
  34. public $rectificativa;
  35. public $serie;
  36. public function __construct()
  37. {
  38. parent::__construct(__CLASS__, 'Factura de cliente', 'ventas', FALSE, FALSE);
  39. }
  40. protected function private_core()
  41. {
  42. /// ¿El usuario tiene permiso para eliminar en esta página?
  43. $this->allow_delete = $this->user->allow_delete_on(__CLASS__);
  44. $this->ppage = $this->page->get('ventas_facturas');
  45. $this->agencia = new agencia_transporte();
  46. $this->agente = FALSE;
  47. $this->agentes = array();
  48. $this->cliente = FALSE;
  49. $this->divisa = new divisa();
  50. $this->ejercicio = new ejercicio();
  51. $this->factura = FALSE;
  52. $this->forma_pago = new forma_pago();
  53. $this->pais = new pais();
  54. $this->rectificada = FALSE;
  55. $this->rectificativa = FALSE;
  56. $this->serie = new serie();
  57. /**
  58. * Si hay alguna extensión de tipo config y texto no_button_pagada,
  59. * desactivamos el botón de pagada/sin pagar.
  60. */
  61. $this->mostrar_boton_pagada = TRUE;
  62. foreach($this->extensions as $ext)
  63. {
  64. if($ext->type == 'config' AND $ext->text == 'no_button_pagada')
  65. {
  66. $this->mostrar_boton_pagada = FALSE;
  67. break;
  68. }
  69. }
  70. /**
  71. * ¿Modificamos la factura?
  72. */
  73. $factura = new factura_cliente();
  74. if( isset($_POST['idfactura']) )
  75. {
  76. $this->factura = $factura->get($_POST['idfactura']);
  77. $this->modificar();
  78. }
  79. else if( isset($_GET['id']) )
  80. {
  81. $this->factura = $factura->get($_GET['id']);
  82. }
  83. if($this->factura)
  84. {
  85. $this->page->title = $this->factura->codigo;
  86. /// cargamos el agente
  87. $agente = new agente();
  88. if( !is_null($this->factura->codagente) )
  89. {
  90. $this->agente = $agente->get($this->factura->codagente);
  91. }
  92. $this->agentes = $agente->all();
  93. /// cargamos el cliente
  94. $cliente = new cliente();
  95. $this->cliente = $cliente->get($this->factura->codcliente);
  96. if( isset($_GET['gen_asiento']) AND isset($_GET['petid']) )
  97. {
  98. if( $this->duplicated_petition($_GET['petid']) )
  99. {
  100. $this->new_error_msg('Petición duplicada. Evita hacer doble clic sobre los botones.');
  101. }
  102. else
  103. {
  104. $this->generar_asiento($this->factura);
  105. }
  106. }
  107. else if( isset($_GET['updatedir']) )
  108. {
  109. $this->actualizar_direccion();
  110. }
  111. else if( isset($_REQUEST['pagada']) )
  112. {
  113. $this->pagar( ($_REQUEST['pagada'] == 'TRUE') );
  114. }
  115. else if( isset($_POST['anular']) )
  116. {
  117. $this->anular_factura();
  118. }
  119. if($this->factura->idfacturarect)
  120. {
  121. $this->rectificada = $factura->get($this->factura->idfacturarect);
  122. }
  123. else
  124. {
  125. $this->get_factura_rectificativa();
  126. }
  127. /// comprobamos la factura
  128. $this->factura->full_test();
  129. }
  130. else
  131. $this->new_error_msg("¡Factura de cliente no encontrada!");
  132. }
  133. public function url()
  134. {
  135. if( !isset($this->factura) )
  136. {
  137. return parent::url ();
  138. }
  139. else if($this->factura)
  140. {
  141. return $this->factura->url();
  142. }
  143. else
  144. return $this->ppage->url();
  145. }
  146. private function modificar()
  147. {
  148. $this->factura->observaciones = $_POST['observaciones'];
  149. $this->factura->numero2 = $_POST['numero2'];
  150. $this->factura->nombrecliente = $_POST['nombrecliente'];
  151. $this->factura->cifnif = $_POST['cifnif'];
  152. $this->factura->codpais = $_POST['codpais'];
  153. $this->factura->provincia = $_POST['provincia'];
  154. $this->factura->ciudad = $_POST['ciudad'];
  155. $this->factura->codpostal = $_POST['codpostal'];
  156. $this->factura->direccion = $_POST['direccion'];
  157. $this->factura->envio_nombre = $_POST['envio_nombre'];
  158. $this->factura->envio_apellidos = $_POST['envio_apellidos'];
  159. $this->factura->envio_codtrans = NULL;
  160. if($_POST['envio_codtrans'] != '')
  161. {
  162. $this->factura->envio_codtrans = $_POST['envio_codtrans'];
  163. }
  164. $this->factura->envio_codigo = $_POST['envio_codigo'];
  165. $this->factura->envio_provincia = $_POST['envio_provincia'];
  166. $this->factura->envio_ciudad = $_POST['envio_ciudad'];
  167. $this->factura->envio_codpostal = $_POST['envio_codpostal'];
  168. $this->factura->envio_direccion = $_POST['envio_direccion'];
  169. $this->factura->codagente = NULL;
  170. $this->factura->porcomision = 0;
  171. if($_POST['codagente'] != '')
  172. {
  173. $this->factura->codagente = $_POST['codagente'];
  174. $this->factura->porcomision = floatval($_POST['porcomision']);
  175. }
  176. /// obtenemos el ejercicio para poder acotar la fecha
  177. $eje0 = $this->ejercicio->get( $this->factura->codejercicio );
  178. if($eje0)
  179. {
  180. $this->factura->fecha = $eje0->get_best_fecha($_POST['fecha'], TRUE);
  181. $this->factura->hora = $_POST['hora'];
  182. }
  183. else
  184. $this->new_error_msg('No se encuentra el ejercicio asociado a la factura.');
  185. /// ¿cambiamos la forma de pago?
  186. if($this->factura->codpago != $_POST['forma_pago'])
  187. {
  188. $this->factura->codpago = $_POST['forma_pago'];
  189. $this->factura->vencimiento = $this->nuevo_vencimiento($this->factura->fecha, $this->factura->codpago);
  190. }
  191. else
  192. {
  193. $this->factura->vencimiento = $_POST['vencimiento'];
  194. }
  195. if( $this->factura->save() )
  196. {
  197. $asiento = $this->factura->get_asiento();
  198. if($asiento)
  199. {
  200. $asiento->fecha = $this->factura->fecha;
  201. if( !$asiento->save() )
  202. {
  203. $this->new_error_msg("Imposible modificar la fecha del asiento.");
  204. }
  205. }
  206. $this->new_message("Factura modificada correctamente.");
  207. $this->new_change('Factura Cliente '.$this->factura->codigo, $this->factura->url());
  208. }
  209. else
  210. $this->new_error_msg("¡Imposible modificar la factura!");
  211. }
  212. private function actualizar_direccion()
  213. {
  214. foreach($this->cliente->get_direcciones() as $dir)
  215. {
  216. if($dir->domfacturacion)
  217. {
  218. $this->factura->cifnif = $this->cliente->cifnif;
  219. $this->factura->nombrecliente = $this->cliente->razonsocial;
  220. $this->factura->apartado = $dir->apartado;
  221. $this->factura->ciudad = $dir->ciudad;
  222. $this->factura->coddir = $dir->id;
  223. $this->factura->codpais = $dir->codpais;
  224. $this->factura->codpostal = $dir->codpostal;
  225. $this->factura->direccion = $dir->direccion;
  226. $this->factura->provincia = $dir->provincia;
  227. if( $this->factura->save() )
  228. {
  229. $this->new_message('Dirección actualizada correctamente.');
  230. }
  231. else
  232. $this->new_error_msg('Imposible actualizar la dirección de la factura.');
  233. break;
  234. }
  235. }
  236. }
  237. private function generar_asiento(&$factura)
  238. {
  239. if( $factura->get_asiento() )
  240. {
  241. $this->new_error_msg('Ya hay un asiento asociado a esta factura.');
  242. }
  243. else
  244. {
  245. $asiento_factura = new asiento_factura();
  246. $asiento_factura->soloasiento = TRUE;
  247. if( $asiento_factura->generar_asiento_venta($factura) )
  248. {
  249. $this->new_message("<a href='".$asiento_factura->asiento->url()."'>Asiento</a> generado correctamente.");
  250. }
  251. foreach($asiento_factura->errors as $err)
  252. {
  253. $this->new_error_msg($err);
  254. }
  255. foreach($asiento_factura->messages as $msg)
  256. {
  257. $this->new_message($msg);
  258. }
  259. }
  260. }
  261. private function pagar($pagada = TRUE)
  262. {
  263. /// ¿Hay asiento?
  264. if( is_null($this->factura->idasiento) )
  265. {
  266. $this->factura->pagada = $pagada;
  267. $this->factura->save();
  268. }
  269. else if(!$pagada AND $this->factura->pagada)
  270. {
  271. /// marcar como impagada
  272. $this->factura->pagada = FALSE;
  273. /// ¿Eliminamos el asiento de pago?
  274. $as1 = new asiento();
  275. $asiento = $as1->get($this->factura->idasientop);
  276. if($asiento)
  277. {
  278. $asiento->delete();
  279. $this->new_message('Asiento de pago eliminado.');
  280. }
  281. $this->factura->idasientop = NULL;
  282. if( $this->factura->save() )
  283. {
  284. $this->new_message('Factura marcada como impagada.');
  285. }
  286. else
  287. {
  288. $this->new_error_msg('Error al modificar la factura.');
  289. }
  290. }
  291. else if($pagada AND !$this->factura->pagada)
  292. {
  293. /// marcar como pagada
  294. $asiento = $this->factura->get_asiento();
  295. if($asiento)
  296. {
  297. /// nos aseguramos que el cliente tenga subcuenta en el ejercicio actual
  298. $subcli = FALSE;
  299. $eje = $this->ejercicio->get_by_fecha( $this->today() );
  300. if($eje)
  301. {
  302. $subcli = $this->cliente->get_subcuenta($eje->codejercicio);
  303. }
  304. $asiento_factura = new asiento_factura();
  305. $this->factura->idasientop = $asiento_factura->generar_asiento_pago($asiento, $this->factura->codpago, $this->today(), $subcli);
  306. if($this->factura->idasientop)
  307. {
  308. $this->factura->pagada = TRUE;
  309. if( $this->factura->save() )
  310. {
  311. $this->new_message('<a href="'.$this->factura->asiento_pago_url().'">Asiento de pago</a> generado.');
  312. }
  313. else
  314. {
  315. $this->new_error_msg('Error al marcar la factura como pagada.');
  316. }
  317. }
  318. foreach($asiento_factura->errors as $err)
  319. {
  320. $this->new_error_msg($err);
  321. }
  322. }
  323. else
  324. {
  325. $this->new_error_msg('No se ha encontrado el asiento de la factura.');
  326. }
  327. }
  328. }
  329. private function nuevo_vencimiento($fecha, $codpago)
  330. {
  331. $vencimiento = $fecha;
  332. $formap = $this->forma_pago->get($codpago);
  333. if($formap)
  334. {
  335. $vencimiento = Date('d-m-Y', strtotime($fecha.' '.$formap->vencimiento));
  336. }
  337. return $vencimiento;
  338. }
  339. private function anular_factura()
  340. {
  341. /// generamos una factura rectificativa a partir de la actual
  342. $factura = clone $this->factura;
  343. $factura->idfactura = NULL;
  344. $factura->numero = NULL;
  345. $factura->numero2 = NULL;
  346. $factura->codigo = NULL;
  347. $factura->idasiento = NULL;
  348. $factura->idfacturarect = $this->factura->idfactura;
  349. $factura->codigorect = $this->factura->codigo;
  350. $factura->codserie = $_POST['codserie'];
  351. $factura->fecha = $this->today();
  352. $factura->hora = $this->hour();
  353. $factura->observaciones = $_POST['motivo'];
  354. $factura->neto = 0 - $factura->neto;
  355. $factura->totalirpf = 0 - $factura->totalirpf;
  356. $factura->totaliva = 0 - $factura->totaliva;
  357. $factura->totalrecargo = 0 - $factura->totalrecargo;
  358. $factura->total = $factura->neto + $factura->totaliva + $factura->totalrecargo - $factura->totalirpf;
  359. if( $factura->save() )
  360. {
  361. $articulo = new articulo();
  362. $error = FALSE;
  363. /// copiamos las líneas en negativo
  364. foreach($this->factura->get_lineas() as $lin)
  365. {
  366. /// actualizamos el stock
  367. $art = $articulo->get($lin->referencia);
  368. if($art)
  369. {
  370. $art->sum_stock($factura->codalmacen, $lin->cantidad);
  371. }
  372. $lin->idlinea = NULL;
  373. $lin->idalbaran = NULL;
  374. $lin->idfactura = $factura->idfactura;
  375. $lin->cantidad = 0 - $lin->cantidad;
  376. $lin->pvpsindto = $lin->pvpunitario * $lin->cantidad;
  377. $lin->pvptotal = $lin->pvpunitario * (100 - $lin->dtopor)/100 * $lin->cantidad;
  378. if( !$lin->save() )
  379. {
  380. $error = TRUE;
  381. }
  382. }
  383. if($error)
  384. {
  385. $factura->delete();
  386. $this->new_error_msg('Se han producido errores al crear la '.FS_FACTURA_RECTIFICATIVA);
  387. }
  388. else
  389. {
  390. $this->new_message( '<a href="'.$factura->url().'">'.ucfirst(FS_FACTURA_RECTIFICATIVA).'</a> creada correctamenmte.' );
  391. $this->generar_asiento($factura);
  392. $this->factura->anulada = TRUE;
  393. $this->factura->save();
  394. }
  395. }
  396. else
  397. {
  398. $this->new_error_msg('Error al anular la factura.');
  399. }
  400. }
  401. private function get_factura_rectificativa()
  402. {
  403. $sql = "SELECT * FROM facturascli WHERE idfacturarect = ".$this->factura->var2str($this->factura->idfactura);
  404. $data = $this->db->select($sql);
  405. if($data)
  406. {
  407. $this->rectificativa = new factura_cliente($data[0]);
  408. }
  409. }
  410. public function get_cuentas_bancarias()
  411. {
  412. $cuentas = array();
  413. $cbc0 = new cuenta_banco_cliente();
  414. foreach($cbc0->all_from_cliente($this->factura->codcliente) as $cuenta)
  415. {
  416. $cuentas[] = $cuenta;
  417. }
  418. return $cuentas;
  419. }
  420. }