InfoTributariaForm.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. "use client"
  2. import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
  3. import { Input } from "@/components/ui/input"
  4. import { Label } from "@/components/ui/label"
  5. import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
  6. import type { InfoTributaria } from "@/types/factura"
  7. import { useConfiguracionesTributarias } from '@/hooks/useConfiguracionesTributarias'
  8. import { Button } from "@/components/ui/button"
  9. import { ExternalLink } from 'lucide-react'
  10. interface InfoTributariaFormProps {
  11. infoTributaria: InfoTributaria
  12. onChange: (field: keyof InfoTributaria, value: string) => void
  13. }
  14. export function InfoTributariaForm({ infoTributaria, onChange }: InfoTributariaFormProps) {
  15. const { configuraciones } = useConfiguracionesTributarias()
  16. const loadConfiguracion = (config: any) => {
  17. onChange('ambiente', config.ambiente)
  18. onChange('tipoEmision', config.tipoEmision)
  19. onChange('razonSocial', config.razonSocial)
  20. onChange('nombreComercial', config.nombreComercial)
  21. onChange('ruc', config.ruc)
  22. onChange('dirMatriz', config.dirMatriz)
  23. onChange('estab', config.estab)
  24. onChange('ptoEmi', config.ptoEmi)
  25. onChange('secuencial', config.secuencial)
  26. // Nota: claveAcceso no se guarda en la base de datos por seguridad
  27. }
  28. return (
  29. <Card>
  30. <CardHeader>
  31. <div className="flex justify-between items-start">
  32. <div>
  33. <CardTitle>Información Tributaria</CardTitle>
  34. <CardDescription>Datos del emisor de la factura</CardDescription>
  35. </div>
  36. {configuraciones.length > 0 && (
  37. <div className="flex gap-2">
  38. <Select onValueChange={(value) => {
  39. const config = configuraciones.find(c => c.id === value)
  40. if (config) {
  41. loadConfiguracion(config)
  42. }
  43. }}>
  44. <SelectTrigger className="w-[200px]">
  45. <SelectValue placeholder="Cargar configuración" />
  46. </SelectTrigger>
  47. <SelectContent>
  48. {configuraciones.filter(c => c.activo).map((config) => (
  49. <SelectItem key={config.id} value={config.id}>
  50. {config.razonSocial} ({config.ruc})
  51. </SelectItem>
  52. ))}
  53. </SelectContent>
  54. </Select>
  55. <Button
  56. variant="outline"
  57. size="sm"
  58. onClick={() => window.open('/configuracion', '_blank')}
  59. >
  60. <ExternalLink className="w-4 h-4" />
  61. </Button>
  62. </div>
  63. )}
  64. </div>
  65. </CardHeader>
  66. <CardContent>
  67. <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  68. <div className="space-y-2">
  69. <Label htmlFor="ambiente">Ambiente</Label>
  70. <Select value={infoTributaria.ambiente} onValueChange={(value) => onChange('ambiente', value)}>
  71. <SelectTrigger>
  72. <SelectValue />
  73. </SelectTrigger>
  74. <SelectContent>
  75. <SelectItem value="1">1 - Pruebas</SelectItem>
  76. <SelectItem value="2">2 - Producción</SelectItem>
  77. </SelectContent>
  78. </Select>
  79. </div>
  80. <div className="space-y-2">
  81. <Label htmlFor="tipoEmision">Tipo Emisión</Label>
  82. <Select value={infoTributaria.tipoEmision} onValueChange={(value) => onChange('tipoEmision', value)}>
  83. <SelectTrigger>
  84. <SelectValue />
  85. </SelectTrigger>
  86. <SelectContent>
  87. <SelectItem value="1">1 - Normal</SelectItem>
  88. </SelectContent>
  89. </Select>
  90. </div>
  91. <div className="space-y-2">
  92. <Label htmlFor="ruc">RUC *</Label>
  93. <Input
  94. id="ruc"
  95. value={infoTributaria.ruc}
  96. onChange={(e) => onChange('ruc', e.target.value)}
  97. placeholder="13 dígitos"
  98. maxLength={13}
  99. />
  100. </div>
  101. <div className="space-y-2">
  102. <Label htmlFor="razonSocial">Razón Social *</Label>
  103. <Input
  104. id="razonSocial"
  105. value={infoTributaria.razonSocial}
  106. onChange={(e) => onChange('razonSocial', e.target.value)}
  107. placeholder="Empresa S.A."
  108. />
  109. </div>
  110. <div className="space-y-2">
  111. <Label htmlFor="nombreComercial">Nombre Comercial *</Label>
  112. <Input
  113. id="nombreComercial"
  114. value={infoTributaria.nombreComercial}
  115. onChange={(e) => onChange('nombreComercial', e.target.value)}
  116. placeholder="Nombre Comercial"
  117. />
  118. </div>
  119. <div className="space-y-2">
  120. <Label htmlFor="claveAcceso">Clave de Acceso *</Label>
  121. <Input
  122. id="claveAcceso"
  123. value={infoTributaria.claveAcceso}
  124. onChange={(e) => onChange('claveAcceso', e.target.value)}
  125. placeholder="49 dígitos"
  126. maxLength={49}
  127. />
  128. </div>
  129. <div className="space-y-2">
  130. <Label htmlFor="estab">Establecimiento</Label>
  131. <Input
  132. id="estab"
  133. value={infoTributaria.estab}
  134. onChange={(e) => onChange('estab', e.target.value)}
  135. placeholder="001"
  136. maxLength={3}
  137. />
  138. </div>
  139. <div className="space-y-2">
  140. <Label htmlFor="ptoEmi">Punto Emisión</Label>
  141. <Input
  142. id="ptoEmi"
  143. value={infoTributaria.ptoEmi}
  144. onChange={(e) => onChange('ptoEmi', e.target.value)}
  145. placeholder="001"
  146. maxLength={3}
  147. />
  148. </div>
  149. <div className="space-y-2">
  150. <Label htmlFor="secuencial">Secuencial</Label>
  151. <Input
  152. id="secuencial"
  153. value={infoTributaria.secuencial}
  154. onChange={(e) => onChange('secuencial', e.target.value)}
  155. placeholder="000000001"
  156. maxLength={9}
  157. />
  158. </div>
  159. <div className="space-y-2 lg:col-span-3">
  160. <Label htmlFor="dirMatriz">Dirección Matriz *</Label>
  161. <Input
  162. id="dirMatriz"
  163. value={infoTributaria.dirMatriz}
  164. onChange={(e) => onChange('dirMatriz', e.target.value)}
  165. placeholder="Av. Principal 123 y Secundaria"
  166. />
  167. </div>
  168. </div>
  169. </CardContent>
  170. </Card>
  171. )
  172. }