ProviderController.php 163 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283
  1. <?php
  2. /*
  3. Desarrollador: Ing. Jean Jairo Benitez Meza
  4. Ultima Modificación: 11/04/2023
  5. Módulo: Gestión de Adquisiciones
  6. */
  7. namespace App\Http\Controllers;
  8. use App\Http\Controllers\Controller;
  9. use App\Http\Controllers\ResponseController;
  10. use App\Http\Controllers\EncryptionController;
  11. use Illuminate\Http\Request;
  12. use Illuminate\Support\Carbon;
  13. use Illuminate\Support\Facades\DB;
  14. use Illuminate\Support\Facades\Validator;
  15. use \Mpdf\Mpdf as PDF;
  16. use PhpOffice\PhpSpreadsheet\Calculation\Category;
  17. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  18. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  19. use PhpOffice\PhpSpreadsheet\IOFactory;
  20. use PhpOffice\PhpSpreadsheet\Worksheet\Table;
  21. use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableStyle;
  22. class ProviderController extends Controller{
  23. private $responseController;
  24. private $encController;
  25. private $resourcesController;
  26. private $arrAlphabet = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","U","V","W","X","Y","Z");
  27. private $arrHeader = array(
  28. array(
  29. 'POSITION' => 'A',
  30. 'CODE' => 'ARTI_IDAR',
  31. 'COLUMN' => 'ID Artículo',
  32. 'OBLIGATORY' => true
  33. ),
  34. array(
  35. 'POSITION' => 'B',
  36. 'CODE' => 'ARTI_NOMB',
  37. 'COLUMN' => 'Artículo',
  38. 'OBLIGATORY' => true
  39. ),
  40. array(
  41. 'POSITION' => 'C',
  42. 'CODE' => 'FAMI_NOMB',
  43. 'COLUMN' => 'Familia',
  44. 'OBLIGATORY' => true
  45. ),
  46. array(
  47. 'POSITION' => 'D',
  48. 'CODE' => 'SUBF_NOMB',
  49. 'COLUMN' => 'Subfamilia',
  50. 'OBLIGATORY' => true
  51. ),
  52. array(
  53. 'POSITION' => 'E',
  54. 'CODE' => 'ARTI_CODI',
  55. 'COLUMN' => 'Código de Barra',
  56. 'OBLIGATORY' => true
  57. ),
  58. array(
  59. 'POSITION' => 'F',
  60. 'CODE' => 'DEAR_COWE',
  61. 'COLUMN' => 'Compra Web',
  62. 'OBLIGATORY' => true
  63. ),
  64. array(
  65. 'POSITION' => 'G',
  66. 'CODE' => 'DEAR_IDUN',
  67. 'COLUMN' => 'Tipo de Unidad',
  68. 'OBLIGATORY' => true
  69. ),
  70. array(
  71. 'POSITION' => 'H',
  72. 'CODE' => 'DEAR_DESC',
  73. 'COLUMN' => 'Descripción',
  74. 'OBLIGATORY' => true
  75. ),
  76. array(
  77. 'POSITION' => 'I',
  78. 'CODE' => 'DEAR_CARA',
  79. 'COLUMN' => 'Características',
  80. 'OBLIGATORY' => false
  81. ),
  82. );
  83. private $arrHeaderDetails = array(
  84. array(
  85. 'POSITION' => 'A',
  86. 'CODE' => 'INAR_IDIN',
  87. 'COLUMN' => 'ID Detalle',
  88. 'OBLIGATORY' => true,
  89. ),
  90. array(
  91. 'POSITION' => 'B',
  92. 'CODE' => 'INAR_CODI',
  93. 'COLUMN' => 'Código',
  94. 'OBLIGATORY' => true,
  95. ),
  96. array(
  97. 'POSITION' => 'C',
  98. 'CODE' => 'INAR_MODE',
  99. 'COLUMN' => 'Modelo',
  100. 'OBLIGATORY' => true,
  101. ),
  102. array(
  103. 'POSITION' => 'D',
  104. 'CODE' => 'INAR_PREC',
  105. 'COLUMN' => 'Precio',
  106. 'OBLIGATORY' => true,
  107. ),
  108. array(
  109. 'POSITION' => 'E',
  110. 'CODE' => 'INAR_MONE',
  111. 'COLUMN' => 'Moneda',
  112. 'OBLIGATORY' => true,
  113. ),
  114. array(
  115. 'POSITION' => 'F',
  116. 'CODE' => 'INAR_MOMI',
  117. 'COLUMN' => 'Monto Mínimo',
  118. 'OBLIGATORY' => true,
  119. ),
  120. array(
  121. 'POSITION' => 'G',
  122. 'CODE' => 'INAR_CARA',
  123. 'COLUMN' => 'Características',
  124. 'OBLIGATORY' => true,
  125. ),
  126. );
  127. public function __construct() {
  128. $this->responseController = new ResponseController();
  129. $this->encController = new EncryptionController();
  130. $this->resourcesController = new ResourcesController();
  131. }
  132. public function getAllProvider($line){
  133. try {
  134. $arrProvider = DB::table('S002V01TPROV')
  135. ->where('PROV_NULI', '=', $line)
  136. ->get([
  137. 'PROV_NUPR AS NUMERO_PROVEEDOR',
  138. 'PROV_NOCO AS RAZON_SOCIAL',
  139. 'PROV_NOMB AS NOMBRE',
  140. 'PROV_APPA AS PRIMER_APELLIDO',
  141. 'PROV_APMA AS SEGUNDO_APELLIDO',
  142. 'PROV_CORR AS CORREO',
  143. 'PROV_LAD1 AS LADA1',
  144. 'PROV_TEL1 AS TELEFONO1',
  145. 'PROV_LAD2 AS LADA2',
  146. 'PROV_TEL2 AS TELEFONO2',
  147. 'PROV_XRFC AS RFC',
  148. 'PROV_XTAX AS TAXID',
  149. 'PROV_CORF AS REGIMEN_FISCAL',
  150. 'PROV_TIPO AS TIPO',
  151. 'PROV_SIWE AS SITIOWEB',
  152. 'PROV_MEPA AS METODO_PAGO',
  153. 'PROV_ESTA AS ESTADO',
  154. 'PROV_USRE AS USUARIO_REGISTRA',
  155. 'PROV_FERE AS FECHA_REGISTRA',
  156. 'PROV_USMO AS USUARIO_MODIFICA',
  157. 'PROV_FEMO AS FECHA_MODIFICA',
  158. 'PROV_CALL AS CALLE',
  159. 'PROV_NUEX AS EXTERIOR',
  160. 'PROV_NUIN AS INTERIOR',
  161. 'PROV_COPO AS CODIGO_POSTAL',
  162. 'PROV_COLO AS COLONIA',
  163. 'PROV_MUNI AS MUNICIPIO',
  164. 'PROV_ENTI AS ENTIDAD',
  165. 'PROV_PAIS AS PAIS',
  166. ]);
  167. $arrResponse = array();
  168. foreach ($arrProvider as $provider) {
  169. $provider = (array) $provider;
  170. $provider['SEGUNDO_APELLIDO'] = $provider['SEGUNDO_APELLIDO'] == null ? '' : $provider['SEGUNDO_APELLIDO'];
  171. $arrReferences = DB::table('S002V01TPRRE')
  172. ->where('PRRE_NULI', '=', $line)
  173. ->where('PRRE_ESTA', '=', 'Activo')
  174. ->where('PRRE_NUPR', '=', $provider['NUMERO_PROVEEDOR'])
  175. ->get([
  176. 'PRRE_IDRE AS NUMERO_REFERENCIA',
  177. 'PRRE_EMPR AS RAZON_SOCIAL',
  178. 'PRRE_CORR AS CORREO',
  179. 'PRRE_LADA AS LADA',
  180. 'PRRE_TELE AS TELEFONO',
  181. 'PRRE_XRFC AS RFC',
  182. 'PRRE_DIRE AS DIRECCION',
  183. 'PRRE_ESTA AS ESTADO',
  184. 'PRRE_USRE AS USUARIO_REGISTRA',
  185. 'PRRE_FERE AS FECHA_REGISTRA',
  186. 'PRRE_USMO AS USUARIO_MODIFICA',
  187. 'PRRE_FEMO AS FECHA_MODIFICA',
  188. ]);
  189. $arrContacts = DB::table('S002V01TPRCO')
  190. ->where('PRCO_NULI', '=', $line)
  191. ->where('PRCO_ESTA', '=', 'Activo')
  192. ->where('PRCO_NUPR', '=', $provider['NUMERO_PROVEEDOR'])
  193. ->get([
  194. 'PRCO_IDCP AS NUMERO_CONTACTO',
  195. 'PRCO_NOMB AS NOMBRE_CONTACTO',
  196. 'PRCO_TIPO AS TIPO_CONTACTO',
  197. 'PRCO_CALL AS CALLE',
  198. 'PRCO_NUEX AS NUMERO_EXTERIOR',
  199. 'PRCO_NUIN AS NUMERO_INTERIOR',
  200. 'PRCO_COPO AS CODIGO_POSTAL',
  201. 'PRCO_COLO AS COLONIA',
  202. 'PRCO_MUNI AS MUNICIPIO',
  203. 'PRCO_ENTI AS ENTIDAD',
  204. 'PRCO_PAIS AS PAIS',
  205. 'PRCO_LAD1 AS LADA1',
  206. 'PRCO_TEL1 AS TELEFONO1',
  207. 'PRCO_LAD2 AS LADA2',
  208. 'PRCO_TEL2 AS TELEFONO2',
  209. 'PRCO_COR1 AS CORREO1',
  210. 'PRCO_COR2 AS CORREO2',
  211. 'PRCO_OBSE AS OBSERVACIONES',
  212. 'PRCO_ESTA AS ESTADO',
  213. 'PRCO_USRE AS USUARIO_REGISTRA',
  214. 'PRCO_FERE AS FECHA_REGISTRA',
  215. 'PRCO_USMO AS USUARIO_MODIFICA',
  216. 'PRCO_FEMO AS FECHA_MODIFICA',
  217. ]);
  218. $arrConditions = DB::table('S002V01TPRCN')
  219. ->where('PRCN_NULI', '=', $line)
  220. ->where('PRCN_ESTA', '=', 'Activo')
  221. ->where('PRCN_NUPR', '=', $provider['NUMERO_PROVEEDOR'])
  222. ->get([
  223. 'PRCN_IDCM AS NUMERO_CONDICION',
  224. 'PRCN_TIPO AS TIPO_CONDICION',
  225. 'PRCN_INFO AS INFORMACION',
  226. 'PRCN_ESTA AS ESTADO',
  227. 'PRCN_USRE AS USUARIO_REGISTRA',
  228. 'PRCN_FERE AS FECHA_REGISTRA',
  229. 'PRCN_USMO AS USUARIO_MODIFICA',
  230. 'PRCN_FEMO AS FECHA_MODIFICA',
  231. ]);
  232. $arrCatalogs = DB::table('S002V01TPRCE')
  233. ->where('PRCE_NULI', '=', $line)
  234. ->where('PRCE_ESTA', '=', 'Activo')
  235. ->where('PRCE_NUPR', '=', $provider['NUMERO_PROVEEDOR'])
  236. ->get([
  237. 'PRCE_IDCE AS NUMERO_CATALAGO',
  238. 'PRCE_CATA AS CATALAGO',
  239. 'PRCE_DESC AS DESCRIPCION',
  240. 'PRCE_XURL AS URL_CATALAGO',
  241. 'PRCE_ESTA AS ESTADO',
  242. 'PRCE_USRE AS USUARIO_REGISTRA',
  243. 'PRCE_FERE AS FECHA_REGISTRA',
  244. 'PRCE_USMO AS USUARIO_MODIFICA',
  245. 'PRCE_FEMO AS FECHA_MODIFICA',
  246. ]);
  247. $arrPayment = json_decode($provider['METODO_PAGO']);
  248. $arrPaymentFormat = array();
  249. foreach ($arrPayment as $key => $payment) {
  250. $arrPaymentFormat[] = [
  251. 'MEPA_IDME' => $key,
  252. 'MEPA_NOMB' => $payment,
  253. ];
  254. }
  255. $provider['REFERENCIAS'] = $arrReferences;
  256. $provider['CONTACTOS'] = $arrContacts;
  257. $provider['CONDICIONES'] = $arrConditions;
  258. $provider['CATALAGOS'] = $arrCatalogs;
  259. $provider['METODOS_PAGO'] = $arrPaymentFormat;
  260. $arrResponse[] = $provider;
  261. }
  262. } catch (\Throwable $th) {
  263. return $this->responseController->makeResponse(true, "ERR_PROVIDER_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
  264. }
  265. return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $arrResponse);
  266. }
  267. public function getProvidersActives($line) {
  268. try {
  269. $arrProvider = DB::table('S002V01TPROV')
  270. ->where('PROV_ESTA', '=', 'Activo')
  271. ->where('PROV_NULI', '=', $line)
  272. ->get([
  273. 'PROV_NUPR AS NUMERO_PROVEEDOR',
  274. 'PROV_NOCO AS RAZON_SOCIAL',
  275. 'PROV_NOMB AS NOMBRE',
  276. 'PROV_APPA AS PRIMER_APELLIDO',
  277. 'PROV_APMA AS SEGUNDO_APELLIDO',
  278. 'PROV_CORR AS CORREO',
  279. 'PROV_LAD1 AS LADA1',
  280. 'PROV_TEL1 AS TELEFONO1',
  281. 'PROV_LAD2 AS LADA2',
  282. 'PROV_TEL2 AS TELEFONO2',
  283. 'PROV_XRFC AS RFC',
  284. 'PROV_XTAX AS TAXID',
  285. 'PROV_CORF AS REGIMEN_FISCAL',
  286. 'PROV_TIPO AS TIPO',
  287. 'PROV_SIWE AS SITIOWEB',
  288. 'PROV_MEPA AS METODO_PAGO',
  289. 'PROV_USRE AS USUARIO_REGISTRA',
  290. 'PROV_FERE AS FECHA_REGISTRA',
  291. 'PROV_USMO AS USUARIO_MODIFICA',
  292. 'PROV_FEMO AS FECHA_MODIFICA',
  293. ]);
  294. } catch (\Throwable $th) {
  295. return $this->responseController->makeResponse(true, "ERR_PROVIDER_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
  296. }
  297. return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $arrProvider);
  298. }
  299. public function getProvidersByNumber($provider, $line) {
  300. try {
  301. $arrProvider = DB::table('S002V01TPROV')
  302. ->where('PROV_NUPR', '=', $provider)
  303. ->where('PROV_ESTA', '=', 'Activo')
  304. ->where('PROV_NULI', '=', $line)
  305. ->first([
  306. 'PROV_NUPR AS NUMERO_PROVEEDOR',
  307. 'PROV_NOCO AS RAZON_SOCIAL',
  308. 'PROV_NOMB AS NOMBRE',
  309. 'PROV_APPA AS PRIMER_APELLIDO',
  310. 'PROV_APMA AS SEGUNDO_APELLIDO',
  311. 'PROV_CORR AS CORREO',
  312. 'PROV_LAD1 AS LADA1',
  313. 'PROV_TEL1 AS TELEFONO1',
  314. 'PROV_LAD2 AS LADA2',
  315. 'PROV_TEL2 AS TELEFONO2',
  316. 'PROV_XRFC AS RFC',
  317. 'PROV_XTAX AS TAXID',
  318. 'PROV_CORF AS REGIMEN_FISCAL',
  319. 'PROV_TIPO AS TIPO',
  320. 'PROV_SIWE AS SITIOWEB',
  321. 'PROV_MEPA AS METODO_PAGO',
  322. 'PROV_USRE AS USUARIO_REGISTRA',
  323. 'PROV_FERE AS FECHA_REGISTRA',
  324. 'PROV_USMO AS USUARIO_MODIFICA',
  325. 'PROV_FEMO AS FECHA_MODIFICA',
  326. ]);
  327. } catch (\Throwable $th) {
  328. return $this->responseController->makeResponse(true, "ERR_PROVIDER_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
  329. }
  330. return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $arrProvider);
  331. }
  332. public function updateProvider(Request $request) {
  333. $validator = Validator::make($request->all(), [
  334. 'line' => 'required|string',
  335. 'user' => 'required|string',
  336. 'obj_response' => 'required|string',
  337. ]);
  338. if ($validator->fails()) {
  339. return $this->responseController->makeResponse(
  340. true,
  341. "ERR_PROVIDER_MOD000: Se encontraron uno o más errores.",
  342. $this->responseController->makeErrors($validator->errors()->messages()),
  343. 401
  344. );
  345. }
  346. DB::beginTransaction();
  347. $requestData = $request->all();
  348. $line = $requestData['line'];
  349. try {
  350. $user = $this->encController->decrypt($request['user']);
  351. } catch (\Throwable $th) {
  352. DB::rollBack();
  353. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD001: No se pudo obtener el usuario.", $th->getMessage(), 500);
  354. }
  355. try {
  356. $obj_response = json_decode($requestData['obj_response']);
  357. } catch (\Throwable $th) {
  358. DB::rollBack();
  359. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD002: Ocurrió un error al obtener los datos del proveedor.", $th->getMessage(), 500);
  360. }
  361. $arrInformationPersonal = (array) $obj_response->INFORMACION;
  362. $arrReferences = (array) $obj_response->REFERENCIAS;
  363. $arrContacts = (array) $obj_response->CONTACTOS;
  364. $arrConditions = (array) $obj_response->CONDICIONES;
  365. $arrPaymentMedia = (array) $obj_response->METODOS_PAGO;
  366. $arrCatalogs = (array) $obj_response->CATALAGOS;
  367. $numeroProveedor = $arrInformationPersonal['NUMERO_PROVEEDOR'];
  368. $currentDate = Carbon::now()->timezone('America/Mazatlan')->toDateTimeString();
  369. $arrPaymentTemp = array();
  370. foreach ($arrPaymentMedia as $payment) {
  371. $arrPaymentTemp[$payment->MEPA_IDME] = $payment->MEPA_NOMB;
  372. }
  373. try {
  374. $strPayment = json_encode($arrPaymentTemp);
  375. } catch (\Throwable $th) {
  376. DB::rollBack();
  377. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD003: Ocurrió un error al obtener los datos del método de pago.", $th->getMessage(), 500);
  378. }
  379. $updatePersonal = [
  380. 'PROV_NOCO' => $arrInformationPersonal['RAZON_SOCIAL'],
  381. 'PROV_NOMB' => $arrInformationPersonal['NOMBRE'],
  382. 'PROV_APPA' => $arrInformationPersonal['PRIMER_APELLIDO'],
  383. 'PROV_APMA' => $arrInformationPersonal['SEGUNDO_APELLIDO'] != '' ? $arrInformationPersonal['SEGUNDO_APELLIDO'] : null,
  384. 'PROV_CORR' => $arrInformationPersonal['CORREO'],
  385. 'PROV_LAD1' => $arrInformationPersonal['LADA1'],
  386. 'PROV_TEL1' => $arrInformationPersonal['TELEFONO1'],
  387. 'PROV_LAD2' => $arrInformationPersonal['LADA2'] != '' ? $arrInformationPersonal['LADA2'] : null,
  388. 'PROV_TEL2' => $arrInformationPersonal['TELEFONO2'] != '' ? $arrInformationPersonal['TELEFONO2'] : null,
  389. 'PROV_XRFC' => $arrInformationPersonal['RFC'],
  390. 'PROV_XTAX' => $arrInformationPersonal['TAXID'] != '' ? $arrInformationPersonal['TAXID'] : null,
  391. 'PROV_CORF' => $arrInformationPersonal['REGIMEN_FISCAL'],
  392. 'PROV_TIPO' => $arrInformationPersonal['TIPO'],
  393. 'PROV_SIWE' => $arrInformationPersonal['SITIOWEB'],
  394. 'PROV_MEPA' => $strPayment,
  395. 'PROV_CALL' => $arrInformationPersonal['CALLE'],
  396. 'PROV_NUEX' => $arrInformationPersonal['EXTERIOR'],
  397. 'PROV_NUIN' => $arrInformationPersonal['INTERIOR'],
  398. 'PROV_COPO' => $arrInformationPersonal['CODIGO_POSTAL'],
  399. 'PROV_COLO' => $arrInformationPersonal['COLONIA'],
  400. 'PROV_MUNI' => $arrInformationPersonal['MUNICIPIO'],
  401. 'PROV_ENTI' => $arrInformationPersonal['ENTIDAD'],
  402. 'PROV_PAIS' => $arrInformationPersonal['PAIS'],
  403. 'PROV_USMO' => $user,
  404. 'PROV_FEMO' => $currentDate,
  405. 'PROV_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  406. ];
  407. try {
  408. $resp = DB::table('S002V01TPROV')->where('PROV_NUPR', '=', $numeroProveedor)->where('PROV_NULI', '=', $line)->update($updatePersonal);
  409. if (!$resp) {
  410. DB::rollBack();
  411. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD004: Ocurrió un error al obtener el contenido.", [], 500);
  412. }
  413. } catch (\Throwable $th) {
  414. DB::rollBack();
  415. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD005: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  416. }
  417. foreach ($arrReferences as $references) {
  418. if ($references->ESTADO == 'Activo' || $references->ESTADO == 'Modificado') {
  419. $updateReferences = [
  420. 'PRRE_EMPR' => $references->RAZON_SOCIAL,
  421. 'PRRE_CORR' => $references->CORREO,
  422. 'PRRE_LADA' => $references->LADA,
  423. 'PRRE_TELE' => $references->TELEFONO,
  424. 'PRRE_XRFC' => $references->RFC,
  425. 'PRRE_DIRE' => $references->DIRECCION,
  426. 'PRRE_USMO' => $user,
  427. 'PRRE_FEMO' => $currentDate,
  428. 'PRRE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  429. ];
  430. try {
  431. $resp = DB::table('S002V01TPRRE')
  432. ->where('PRRE_IDRE', '=', $references->NUMERO_REFERENCIA)
  433. ->where('PRRE_NUPR', '=', $numeroProveedor)
  434. ->where('PRRE_NULI', '=', $line)
  435. ->update($updateReferences);
  436. if (!$resp) {
  437. DB::rollBack();
  438. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD006: Ocurrió un error al obtener el contenido. ", [], 500);
  439. }
  440. } catch (\Throwable $th) {
  441. DB::rollBack();
  442. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD007: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  443. }
  444. }else if($references->ESTADO == 'Nuevo') {
  445. $insertReferences = [
  446. 'PRRE_NUPR' => $numeroProveedor,
  447. 'PRRE_EMPR' => $references->RAZON_SOCIAL,
  448. 'PRRE_CORR' => $references->CORREO,
  449. 'PRRE_LADA' => $references->LADA,
  450. 'PRRE_TELE' => $references->TELEFONO,
  451. 'PRRE_XRFC' => $references->RFC,
  452. 'PRRE_DIRE' => $references->DIRECCION,
  453. 'PRRE_NULI' => $line,
  454. 'PRRE_USRE' => $user,
  455. 'PRRE_FERE' => $currentDate,
  456. 'PRRE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  457. ];
  458. try {
  459. $resp = DB::table('S002V01TPRRE')->insert($insertReferences);
  460. if (!$resp) {
  461. DB::rollBack();
  462. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD008: Ocurrió un error al obtener el contenido.", [], 500);
  463. }
  464. } catch (\Throwable $th) {
  465. DB::rollBack();
  466. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD009: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  467. }
  468. } else if($references->ESTADO == 'Eliminado'){
  469. $updateReferences = [
  470. 'PRRE_ESTA' => 'Eliminado',
  471. 'PRRE_USMO' => $user,
  472. 'PRRE_FEMO' => $currentDate,
  473. 'PRRE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  474. ];
  475. try {
  476. $resp = DB::table('S002V01TPRRE')
  477. ->where('PRRE_IDRE', '=', $references->NUMERO_REFERENCIA)
  478. ->where('PRRE_NUPR', '=', $numeroProveedor)
  479. ->where('PRRE_NULI', '=', $line)
  480. ->update($updateReferences);
  481. if (!$resp) {
  482. DB::rollBack();
  483. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD010: Ocurrió un error al obtener el contenido.", [], 500);
  484. }
  485. } catch (\Throwable $th) {
  486. DB::rollBack();
  487. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD011: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  488. }
  489. }
  490. }
  491. foreach ($arrContacts as $contacts) {
  492. if ($contacts->ESTADO == 'Activo' && $contacts->ESTADO == 'Modificado') {
  493. $updateContacts = [
  494. 'PRCO_NOMB' => $contacts->NOMBRE_CONTACTO,
  495. 'PRCO_TIPO' => $contacts->TIPO_CONTACTO,
  496. 'PRCO_CALL' => $contacts->CALLE,
  497. 'PRCO_NUEX' => $contacts->NUMERO_EXTERIOR,
  498. 'PRCO_NUIN' => $contacts->NUMERO_INTERIOR != '' ? $contacts->NUMERO_INTERIOR : null,
  499. 'PRCO_COPO' => $contacts->CODIGO_POSTAL,
  500. 'PRCO_COLO' => $contacts->SUBURB,
  501. 'PRCO_MUNI' => $contacts->MUNICIPIO,
  502. 'PRCO_ENTI' => $contacts->ENTIDAD,
  503. 'PRCO_PAIS' => $contacts->PAIS,
  504. 'PRCO_TEL1' => $contacts->TELEFONO1,
  505. 'PRCO_TEL2' => $contacts->TELEFONO2 != '' ? $contacts->TELEFONO2 : null,
  506. 'PRCO_COR1' => $contacts->CORREO1,
  507. 'PRCO_COR2' => $contacts->CORREO2 != '' ? $contacts->CORREO2 : null,
  508. 'PRCO_OBSE' => $contacts->OBSERVACIONES,
  509. 'PRCO_USMO' => $user,
  510. 'PRCO_FEMO' => $currentDate,
  511. 'PRCO_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  512. ];
  513. try {
  514. $resp = DB::table('S002V01TPRCO')
  515. ->where('PRCO_IDCP', '=', $contacts->NUMERO_CONTACTO)
  516. ->where('PRCO_NUPR', '=', $numeroProveedor)
  517. ->where('PRCO_NULI', '=', $line)
  518. ->update($updateContacts);
  519. if (!$resp) {
  520. DB::rollBack();
  521. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD012: Ocurrió un error al obtener el contenido.", [], 500);
  522. }
  523. } catch (\Throwable $th) {
  524. DB::rollBack();
  525. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD013: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  526. }
  527. }else if($contacts->ESTADO == 'Nuevo'){
  528. $insertContacts = [
  529. 'PRCO_NUPR' => $numeroProveedor,
  530. 'PRCO_NOMB' => $contacts->NOMBRE_CONTACTO,
  531. 'PRCO_TIPO' => $contacts->TIPO_CONTACTO,
  532. 'PRCO_CALL' => $contacts->CALLE,
  533. 'PRCO_NUEX' => $contacts->NUMERO_EXTERIOR,
  534. 'PRCO_NUIN' => $contacts->NUMERO_INTERIOR != '' ? $contacts->NUMERO_INTERIOR : null,
  535. 'PRCO_COPO' => $contacts->CODIGO_POSTAL,
  536. 'PRCO_COLO' => $contacts->COLONIA,
  537. 'PRCO_MUNI' => $contacts->MUNICIPIO,
  538. 'PRCO_ENTI' => $contacts->ENTIDAD,
  539. 'PRCO_PAIS' => $contacts->PAIS,
  540. 'PRCO_LAD1' => $contacts->LADA1,
  541. 'PRCO_TEL1' => $contacts->TELEFONO1,
  542. 'PRCO_LAD2' => $contacts->LADA2 != '' ? $contacts->LADA2 : null,
  543. 'PRCO_TEL2' => $contacts->TELEFONO2 != '' ? $contacts->TELEFONO2 : null,
  544. 'PRCO_COR1' => $contacts->CORREO1,
  545. 'PRCO_COR2' => $contacts->CORREO2 != '' ? $contacts->CORREO2 : null,
  546. 'PRCO_OBSE' => $contacts->OBSERVACIONES,
  547. 'PRCO_NULI' => $line,
  548. 'PRCO_USRE' => $user,
  549. 'PRCO_FERE' => $currentDate,
  550. 'PRCO_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  551. ];
  552. try {
  553. $resp = DB::table('S002V01TPRCO')->insert($insertContacts);
  554. if (!$resp) {
  555. DB::rollBack();
  556. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD014: Ocurrió un error al obtener el contenido.", [], 500);
  557. }
  558. } catch (\Throwable $th) {
  559. DB::rollBack();
  560. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD015: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  561. }
  562. }else if($contacts->ESTADO == 'Eliminado'){
  563. $updateContacts = [
  564. 'PRCO_ESTA' => 'Eliminado',
  565. 'PRCO_USMO' => $user,
  566. 'PRCO_FEMO' => $currentDate,
  567. 'PRCO_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  568. ];
  569. try {
  570. $resp = DB::table('S002V01TPRCO')
  571. ->where('PRCO_IDCP', '=', $contacts->NUMERO_CONTACTO)
  572. ->where('PRCO_NUPR', '=', $numeroProveedor)
  573. ->where('PRCO_NULI', '=', $line)
  574. ->update($updateContacts);
  575. if (!$resp) {
  576. DB::rollBack();
  577. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD016: Ocurrió un error al obtener el contenido.", [], 500);
  578. }
  579. } catch (\Throwable $th) {
  580. DB::rollBack();
  581. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD017: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  582. }
  583. }
  584. }
  585. foreach ($arrConditions as $conditions) {
  586. if ($conditions->ESTADO == 'Activo' && $conditions->ESTADO == 'Modificado') {
  587. $updateConditions = [
  588. 'PRCN_TIPO' => $conditions->TIPO_CONDICION,
  589. 'PRCN_INFO' => $conditions->INFORMACION,
  590. 'PRCN_USMO' => $user,
  591. 'PRCN_FEMO' => $currentDate,
  592. 'PRCN_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  593. ];
  594. try {
  595. $resp = DB::table('S002V01TPRCN')
  596. ->where('PRCN_IDCM', '=', $conditions->NUMERO_CONDICION)
  597. ->where('PRCN_NUPR', '=', $numeroProveedor)
  598. ->where('PRCN_NULI', '=', $line)
  599. ->update($updateConditions);
  600. if (!$resp) {
  601. DB::rollBack();
  602. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD018: Ocurrió un error al obtener el contenido.", [], 500);
  603. }
  604. } catch (\Throwable $th) {
  605. DB::rollBack();
  606. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD019: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  607. }
  608. }else if($conditions->ESTADO == 'Nuevo'){
  609. $insertConditions = [
  610. 'PRCN_NUPR' => $numeroProveedor,
  611. 'PRCN_TIPO' => $conditions->TIPO_CONDICION,
  612. 'PRCN_INFO' => $conditions->INFORMACION,
  613. 'PRCN_NULI' => $line,
  614. 'PRCN_USRE' => $user,
  615. 'PRCN_FERE' => $currentDate,
  616. 'PRCN_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  617. ];
  618. try {
  619. $resp = DB::table('S002V01TPRCN')->insert($insertConditions);
  620. if (!$resp) {
  621. DB::rollBack();
  622. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD020: Ocurrió un error al obtener el contenido.", [], 500);
  623. }
  624. } catch (\Throwable $th) {
  625. DB::rollBack();
  626. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD021: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  627. }
  628. }else if ($conditions->ESTADO == 'Eliminado'){
  629. try {
  630. $validateRegister = DB::table('S002V01TPRCN')
  631. ->where('PRCN_IDCM', '=', $conditions->NUMERO_CONDICION)
  632. ->where('PRCN_NUPR', '=', $numeroProveedor)
  633. ->where('PRCN_NULI', '=', $line)
  634. ->exists();
  635. } catch (\Throwable $th) {
  636. DB::rollBack();
  637. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD023: Ocurrió un error al validar el registro.", $th->getMessage(), 500);
  638. }
  639. if ($validateRegister) {
  640. try {
  641. $validateUpdate = DB::table('S002V01TPRCN')
  642. ->where('PRCN_IDCM', '=', $conditions->NUMERO_CONDICION)
  643. ->where('PRCN_NUPR', '=', $numeroProveedor)
  644. ->where('PRCN_NULI', '=', $line)
  645. ->update([
  646. 'PRCN_ESTA' => 'Eliminado',
  647. 'PRCN_USMO' => $user,
  648. 'PRCN_FEMO' => $currentDate,
  649. 'PRCN_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  650. ]);
  651. } catch (\Throwable $th) {
  652. DB::rollBack();
  653. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD023: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  654. }
  655. if (!$validateUpdate) {
  656. DB::rollBack();
  657. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD022: Ocurrió un error al obtener el contenido.", [], 500);
  658. }
  659. }
  660. }
  661. }
  662. foreach ($arrCatalogs as $catalogs) {
  663. if ($catalogs->ESTADO == 'Activo' || $catalogs->ESTADO == 'Modificado') {
  664. $updateCatalogs = [
  665. 'PRCE_CATA' => $catalogs->CATALAGO,
  666. 'PRCE_DESC' => $catalogs->DESCRIPCION,
  667. 'PRCE_XURL' => $catalogs->URL_CATALAGO,
  668. 'PRCE_USMO' => $user,
  669. 'PRCE_FEMO' => $currentDate,
  670. 'PRCE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  671. ];
  672. try {
  673. $resp = DB::table('S002V01TPRCE')
  674. ->where('PRCE_IDCE', '=', $catalogs->NUMERO_CATALAGO)
  675. ->where('PRCE_NUPR', '=', $numeroProveedor)
  676. ->where('PRCE_NULI', '=', $line)
  677. ->update($updateCatalogs);
  678. if (!$resp) {
  679. DB::rollBack();
  680. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD024: Ocurrió un error al obtener el contenido.", [], 500);
  681. }
  682. } catch (\Throwable $th) {
  683. DB::rollBack();
  684. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD025: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  685. }
  686. }else if($catalogs->ESTADO == 'Nuevo'){
  687. $insertCatalogs = [
  688. 'PRCE_NUPR' => $numeroProveedor,
  689. 'PRCE_CATA' => $catalogs->CATALAGO,
  690. 'PRCE_DESC' => $catalogs->DESCRIPCION,
  691. 'PRCE_XURL' => $catalogs->URL_CATALAGO,
  692. 'PRCE_NULI' => $line,
  693. 'PRCE_USRE' => $user,
  694. 'PRCE_FERE' => $currentDate,
  695. 'PRCE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  696. ];
  697. try {
  698. $resp = DB::table('S002V01TPRCE')->insert($insertCatalogs);
  699. if (!$resp) {
  700. DB::rollBack();
  701. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD026: Ocurrió un error al obtener el contenido.", [], 500);
  702. }
  703. } catch (\Throwable $th) {
  704. DB::rollBack();
  705. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD027: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  706. }
  707. }else if($catalogs->ESTADO == 'Eliminado'){
  708. try {
  709. $validateExists = DB::table('S002V01TPRCE')
  710. ->where('PRCE_IDCE', '=', $catalogs->NUMERO_CATALAGO)
  711. ->where('PRCE_NUPR', '=', $numeroProveedor)
  712. ->where('PRCE_NULI', '=', $line)
  713. ->exists();
  714. } catch (\Throwable $th) {
  715. DB::rollBack();
  716. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD029: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  717. }
  718. if ($validateExists) {
  719. try {
  720. $validateDelete = DB::table('S002V01TPRCE')
  721. ->where('PRCE_IDCE', '=', $catalogs->NUMERO_CATALAGO)
  722. ->where('PRCE_NUPR', '=', $numeroProveedor)
  723. ->where('PRCE_NULI', '=', $line)
  724. ->update([
  725. 'PRCE_ESTA' => 'Eliminado',
  726. 'PRCE_USMO' => $user,
  727. 'PRCE_FEMO' => $currentDate,
  728. 'PRCE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  729. ]);
  730. } catch (\Throwable $th) {
  731. DB::rollBack();
  732. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD029: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  733. }
  734. if (!$validateDelete) {
  735. DB::rollBack();
  736. return $this->responseController->makeResponse(true, "ERR_PROVIDER_MOD028: Ocurrió un error al obtener el contenido.", [], 500);
  737. }
  738. }
  739. }
  740. }
  741. DB::commit();
  742. return $this->responseController->makeResponse(false, "EXITO: Modificación Exitosa");
  743. }
  744. public function registerProvider(Request $request) {
  745. $validator = Validator::make($request->all(), [
  746. 'line' => 'required|string',
  747. 'user' => 'required|string',
  748. 'obj_response' => 'required|string',
  749. ]);
  750. if ($validator->fails()) {
  751. return $this->responseController->makeResponse(
  752. true,
  753. "ERR_PROVIDER_REG000: Se encontraron uno o más errores.",
  754. $this->responseController->makeErrors($validator->errors()->messages()),
  755. 401
  756. );
  757. }
  758. DB::beginTransaction();
  759. $requestData = $request->all();
  760. $line = $requestData['line'];
  761. try {
  762. $user = $this->encController->decrypt($requestData['user']);
  763. } catch (\Throwable $th) {
  764. DB::rollBack();
  765. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG001: Ocurrió un error al obtener el usuario.", $th->getMessage(), 500);
  766. }
  767. try {
  768. $obj_response = json_decode($requestData['obj_response']);
  769. } catch (\Throwable $th) {
  770. DB::rollBack();
  771. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG002: Ocurrió un error al obtener los datos del proveedor.", $th->getMessage(), 500);
  772. }
  773. $arrInformationPersonal = (array) $obj_response->INFORMACION;
  774. $arrReferences = (array) $obj_response->REFERENCIAS;
  775. $arrContacts = (array) $obj_response->CONTACTOS;
  776. $arrConditions = (array) $obj_response->CONDICIONES;
  777. $arrPaymentMedia = (array) $obj_response->METODOS_PAGO;
  778. $arrCatalogs = (array) $obj_response->CATALAGOS;
  779. $currentDate = Carbon::now()->timezone('America/Mazatlan')->toDateTimeString();
  780. $arrPaymentTemp = array();
  781. foreach ($arrPaymentMedia as $payment) {
  782. $arrPaymentTemp[$payment->MEPA_IDME] = $payment->MEPA_NOMB;
  783. }
  784. try {
  785. $strPayment = json_encode($arrPaymentTemp);
  786. } catch (\Throwable $th) {
  787. DB::rollBack();
  788. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG003: Ocurrió un error al obtener los métodos de pago del proveedor.", $th->getMessage(), 500);
  789. }
  790. $insertPersonal = [
  791. 'PROV_NOCO' => $arrInformationPersonal['RAZON_SOCIAL'],
  792. 'PROV_NOMB' => $arrInformationPersonal['NOMBRE'],
  793. 'PROV_APPA' => $arrInformationPersonal['PRIMER_APELLIDO'],
  794. 'PROV_APMA' => $arrInformationPersonal['SEGUNDO_APELLIDO'] != '' ? $arrInformationPersonal['SEGUNDO_APELLIDO'] : null,
  795. 'PROV_CORR' => $arrInformationPersonal['CORREO'],
  796. 'PROV_LAD1' => $arrInformationPersonal['LADA1'],
  797. 'PROV_TEL1' => $arrInformationPersonal['TELEFONO1'],
  798. 'PROV_LAD2' => $arrInformationPersonal['LADA2'] != '' ? $arrInformationPersonal['LADA2'] : null,
  799. 'PROV_TEL2' => $arrInformationPersonal['TELEFONO2'] != '' ? $arrInformationPersonal['TELEFONO2'] : null,
  800. 'PROV_XRFC' => $arrInformationPersonal['RFC'],
  801. 'PROV_XTAX' => $arrInformationPersonal['TAXID'] != '' ? $arrInformationPersonal['TAXID'] : null,
  802. 'PROV_CORF' => $arrInformationPersonal['REGIMEN_FISCAL'],
  803. 'PROV_TIPO' => $arrInformationPersonal['TIPO'],
  804. 'PROV_SIWE' => $arrInformationPersonal['SITIOWEB'],
  805. // 'PROV_SIWE' => $arrInformationPersonal['SITIO_WEB'],
  806. 'PROV_CALL' => $arrInformationPersonal['CALLE'],
  807. 'PROV_NUEX' => $arrInformationPersonal['EXTERIOR'],
  808. 'PROV_NUIN' => $arrInformationPersonal['INTERIOR'],
  809. 'PROV_COPO' => $arrInformationPersonal['CODIGO_POSTAL'],
  810. 'PROV_COLO' => $arrInformationPersonal['COLONIA'],
  811. 'PROV_MUNI' => $arrInformationPersonal['MUNICIPIO'],
  812. 'PROV_ENTI' => $arrInformationPersonal['ENTIDAD'],
  813. 'PROV_PAIS' => $arrInformationPersonal['PAIS'],
  814. 'PROV_MEPA' => $strPayment,
  815. 'PROV_NULI' => $line,
  816. 'PROV_USRE' => $user,
  817. 'PROV_FERE' => $currentDate,
  818. 'PROV_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  819. ];
  820. try {
  821. $idProdiver = DB::table('S002V01TPROV')->insertGetId($insertPersonal);
  822. } catch (\Throwable $th) {
  823. DB::rollBack();
  824. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG004: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  825. }
  826. foreach ($arrReferences as $references) {
  827. if ($references->ESTADO == 'Activo' || $references->ESTADO == 'Nuevo') {
  828. $insertReferences = [
  829. 'PRRE_NUPR' => $idProdiver,
  830. 'PRRE_EMPR' => $references->RAZON_SOCIAL,
  831. 'PRRE_CORR' => $references->CORREO,
  832. 'PRRE_LADA' => $references->LADA,
  833. 'PRRE_TELE' => $references->TELEFONO,
  834. 'PRRE_XRFC' => $references->RFC,
  835. 'PRRE_DIRE' => $references->DIRECCION,
  836. 'PRRE_NULI' => $line,
  837. 'PRRE_USRE' => $user,
  838. 'PRRE_FERE' => $currentDate,
  839. 'PRRE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  840. ];
  841. try {
  842. $resp = DB::table('S002V01TPRRE')->insert($insertReferences);
  843. if (!$resp) {
  844. DB::rollBack();
  845. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG005: Ocurrió un error al obtener el contenido.", [], 500);
  846. }
  847. } catch (\Throwable $th) {
  848. DB::rollBack();
  849. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG006: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  850. }
  851. }
  852. }
  853. foreach ($arrContacts as $contacts) {
  854. if ($contacts->ESTADO == 'Activo' || $contacts->ESTADO == 'Nuevo') {
  855. $insertContacts = [
  856. 'PRCO_NUPR' => $idProdiver,
  857. 'PRCO_NOMB' => $contacts->NOMBRE_CONTACTO,
  858. 'PRCO_TIPO' => $contacts->TIPO_CONTACTO,
  859. 'PRCO_CALL' => $contacts->CALLE,
  860. 'PRCO_NUEX' => $contacts->NUMERO_EXTERIOR,
  861. 'PRCO_NUIN' => $contacts->NUMERO_INTERIOR != '' ? $contacts->NUMERO_INTERIOR : null,
  862. 'PRCO_COPO' => $contacts->CODIGO_POSTAL,
  863. 'PRCO_COLO' => $contacts->COLONIA,
  864. 'PRCO_MUNI' => $contacts->MUNICIPIO,
  865. 'PRCO_ENTI' => $contacts->ENTIDAD,
  866. 'PRCO_PAIS' => $contacts->PAIS,
  867. 'PRCO_LAD1' => $contacts->LADA1,
  868. 'PRCO_TEL1' => $contacts->TELEFONO1,
  869. 'PRCO_LAD2' => $contacts->LADA2 != '' ? $contacts->LADA2 : null,
  870. 'PRCO_TEL2' => $contacts->TELEFONO2 != '' ? $contacts->TELEFONO2 : null,
  871. 'PRCO_COR1' => $contacts->CORREO1,
  872. 'PRCO_COR2' => $contacts->CORREO2 != '' ? $contacts->CORREO2 : null,
  873. 'PRCO_OBSE' => $contacts->OBSERVACIONES,
  874. 'PRCO_NULI' => $line,
  875. 'PRCO_USRE' => $user,
  876. 'PRCO_FERE' => $currentDate,
  877. 'PRCO_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  878. ];
  879. try {
  880. $resp = DB::table('S002V01TPRCO')->insert($insertContacts);
  881. if (!$resp) {
  882. DB::rollBack();
  883. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG007: Ocurrió un error al obtener el contenido.", [], 500);
  884. }
  885. } catch (\Throwable $th) {
  886. DB::rollBack();
  887. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG008: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  888. }
  889. }
  890. }
  891. foreach ($arrConditions as $conditions) {
  892. if ($conditions->ESTADO == 'Activo') {
  893. $insertConditions = [
  894. 'PRCN_NUPR' => $idProdiver,
  895. 'PRCN_TIPO' => $conditions->TIPO_CONDICION,
  896. 'PRCN_INFO' => $conditions->INFORMACION,
  897. 'PRCN_NULI' => $line,
  898. 'PRCN_USRE' => $user,
  899. 'PRCN_FERE' => $currentDate,
  900. 'PRCN_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  901. ];
  902. try {
  903. $resp = DB::table('S002V01TPRCN')->insert($insertConditions);
  904. if (!$resp) {
  905. DB::rollBack();
  906. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG009: Ocurrió un error al obtener el contenido.", [], 500);
  907. }
  908. } catch (\Throwable $th) {
  909. DB::rollBack();
  910. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG010: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  911. }
  912. }
  913. }
  914. foreach ($arrCatalogs as $catalogs) {
  915. if ($catalogs->ESTADO == 'Activo' || $catalogs->ESTADO == 'Nuevo') {
  916. $insertCatalogs = [
  917. 'PRCE_NUPR' => $idProdiver,
  918. 'PRCE_CATA' => $catalogs->CATALAGO,
  919. 'PRCE_DESC' => $catalogs->DESCRIPCION,
  920. 'PRCE_XURL' => $catalogs->URL_CATALAGO,
  921. 'PRCE_NULI' => $line,
  922. 'PRCE_USRE' => $user,
  923. 'PRCE_FERE' => $currentDate,
  924. 'PRCE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  925. ];
  926. try {
  927. $resp = DB::table('S002V01TPRCE')->insert($insertCatalogs);
  928. if (!$resp) {
  929. DB::rollBack();
  930. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG011: Ocurrió un error al obtener el contenido.", [], 500);
  931. }
  932. } catch (\Throwable $th) {
  933. DB::rollBack();
  934. return $this->responseController->makeResponse(true, "ERR_PROVIDER_REG012: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  935. }
  936. }
  937. }
  938. DB::commit();
  939. return $this->responseController->makeResponse(false, "EXITO: Registro Exitoso");
  940. }
  941. public function deleteProvider(Request $request) {
  942. $validator = Validator::make($request->all(), [
  943. 'line' => 'required|string',
  944. 'user' => 'required|string',
  945. 'numero_proveedor' => 'required|string'
  946. ]);
  947. if ($validator->fails()) {
  948. return $this->responseController->makeResponse(
  949. true,
  950. "ERR_PROVIDER_DEL000: Se encontraron uno o más errores.",
  951. $this->responseController->makeErrors($validator->errors()->messages()),
  952. 401
  953. );
  954. }
  955. DB::beginTransaction();
  956. $requestData = $request->all();
  957. $currentDate = Carbon::now()->timezone('America/Mazatlan')->toDateTimeString();
  958. $line = $requestData['line'];
  959. try {
  960. $numeroProveedor = $this->encController->decrypt($requestData['numero_proveedor']);
  961. } catch (\Throwable $th) {
  962. DB::rollBack();
  963. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL001: Ocurrió un error al obtener el número del proveedor.", $th->getMessage(), 500);
  964. }
  965. try {
  966. $user = $this->encController->decrypt($requestData['user']);
  967. } catch (\Throwable $th) {
  968. DB::rollBack();
  969. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL002: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  970. }
  971. $update = [
  972. 'PROV_ESTA' => 'Eliminado',
  973. 'PROV_USMO' => $user,
  974. 'PROV_FEMO' => $currentDate,
  975. 'PROV_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  976. ];
  977. try {
  978. $resp = DB::table('S002V01TPROV')->where('PROV_NUPR', '=', $numeroProveedor)->where('PROV_NULI', '=', $line)->update($update);
  979. if (!$resp) {
  980. DB::rollBack();
  981. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL003: Ocurrió un error al obtener el contenido. ", [], 500);
  982. }
  983. } catch (\Throwable $th) {
  984. DB::rollBack();
  985. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL004: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  986. }
  987. $update = [
  988. 'PRRE_ESTA' => 'Eliminado',
  989. 'PRRE_USMO' => $user,
  990. 'PRRE_FEMO' => $currentDate,
  991. 'PRRE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  992. ];
  993. try {
  994. $resp = DB::table('S002V01TPRRE')->where('PRRE_NUPR', '=', $numeroProveedor)->where('PRRE_NULI', '=', $line)->update($update);
  995. if (!$resp) {
  996. DB::rollBack();
  997. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL005: Ocurrió un error al obtener el contenido. ", [], 500);
  998. }
  999. } catch (\Throwable $th) {
  1000. DB::rollBack();
  1001. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL006: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  1002. }
  1003. $update = [
  1004. 'PRCO_ESTA' => 'Eliminado',
  1005. 'PRCO_USMO' => $user,
  1006. 'PRCO_FEMO' => $currentDate,
  1007. 'PRCO_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  1008. ];
  1009. try {
  1010. $resp = DB::table('S002V01TPRCO')->where('PRCO_NUPR', '=', $numeroProveedor)->where('PRCO_NULI', '=', $line)->update($update);
  1011. if (!$resp) {
  1012. DB::rollBack();
  1013. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL007: Ocurrió un error al obtener el contenido. ", [], 500);
  1014. }
  1015. } catch (\Throwable $th) {
  1016. DB::rollBack();
  1017. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL008: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  1018. }
  1019. $update = [
  1020. 'PRCN_ESTA' => 'Eliminado',
  1021. 'PRCN_USMO' => $user,
  1022. 'PRCN_FEMO' => $currentDate,
  1023. 'PRCN_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  1024. ];
  1025. try {
  1026. $resp = DB::table('S002V01TPRCN')->where('PRCN_NUPR', '=', $numeroProveedor)->where('PRCN_NULI', '=', $line)->update($update);
  1027. if (!$resp) {
  1028. DB::rollBack();
  1029. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL009: Ocurrió un error al obtener el contenido. ", [], 500);
  1030. }
  1031. } catch (\Throwable $th) {
  1032. DB::rollBack();
  1033. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL010: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  1034. }
  1035. $update = [
  1036. 'PRCE_ESTA' => 'Eliminado',
  1037. 'PRCE_USMO' => $user,
  1038. 'PRCE_FEMO' => $currentDate,
  1039. 'PRCE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
  1040. ];
  1041. try {
  1042. $resp = DB::table('S002V01TPRCE')->where('PRCE_NUPR', '=', $numeroProveedor)->where('PRCE_NULI', '=', $line)->update($update);
  1043. if (!$resp) {
  1044. DB::rollBack();
  1045. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL011: Ocurrió un error al obtener el contenido. ", [], 500);
  1046. }
  1047. } catch (\Throwable $th) {
  1048. DB::rollBack();
  1049. return $this->responseController->makeResponse(true, "ERR_PROVIDER_DEL012: Ocurrió un error al obtener el contenido.", $th->getMessage(), 500);
  1050. }
  1051. DB::commit();
  1052. return $this->responseController->makeResponse(false, "EXITO: Eliminación correcta",);
  1053. }
  1054. public function getProviderByArtitle(Request $request) {
  1055. $validator = Validator::make($request->all(), [
  1056. 'NUMERO_ARTICULO' => 'required|string',
  1057. 'NUMERO_LINEA' => 'required|string',
  1058. ]);
  1059. if ($validator->fails()) {
  1060. return $this->responseController->makeResponse(
  1061. true,
  1062. "ERR_PROVIDER_MOD000: Se encontraron uno o más errores.",
  1063. $this->responseController->makeErrors($validator->errors()->messages()),
  1064. 401
  1065. );
  1066. }
  1067. $response = $request->all();
  1068. $numeroArticulo = $this->encController->decrypt($response['NUMERO_ARTICULO']);
  1069. try {
  1070. $arrDescription = DB::table('S002V01TDEAR')
  1071. ->where('DEAR_ESTA', '=', 'Activo')
  1072. ->where('DEAR_IDAR', '=', $numeroArticulo)
  1073. ->join('S002V01TPROV', 'DEAR_NUPR', '=', 'PROV_NUPR')
  1074. ->get([
  1075. 'DEAR_IDDE AS NUMERO_DESCRIPTION',
  1076. 'PROV_NUPR AS NUMERO_PROVEEDOR',
  1077. 'PROV_NOCO AS RAZON_SOCIAL',
  1078. 'PROV_NOMB AS NOMBRE',
  1079. 'PROV_APPA AS PRIMER_APELLIDO',
  1080. 'PROV_APMA AS SEGUNDO_APELLIDO',
  1081. 'PROV_CORR AS CORREO',
  1082. 'PROV_LAD1 AS LADA1',
  1083. 'PROV_TEL1 AS TELEFONO1',
  1084. 'PROV_LAD2 AS LADA2',
  1085. 'PROV_TEL2 AS TELEFONO2',
  1086. 'PROV_XRFC AS RFC',
  1087. 'PROV_XTAX AS TAXID',
  1088. 'PROV_CORF AS REGIMEN_FISCAL',
  1089. 'PROV_TIPO AS TIPO',
  1090. 'PROV_SIWE AS SITIOWEB',
  1091. 'PROV_MEPA AS METODO_PAGO',
  1092. 'PROV_ESTA AS ESTADO',
  1093. 'PROV_USRE AS USUARIO_REGISTRA',
  1094. 'PROV_FERE AS FECHA_REGISTRA',
  1095. 'PROV_USMO AS USUARIO_MODIFICA',
  1096. 'PROV_FEMO AS FECHA_MODIFICA',
  1097. ]);
  1098. } catch (\Throwable $th) {
  1099. return $this->responseController->makeResponse(true, "ERR_PROVIDER_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
  1100. }
  1101. return $this->responseController->makeResponse(false, "ÉXITO", $arrDescription);
  1102. }
  1103. public function generateSheetProvider($encProvider, $encUser, $line) {
  1104. try {
  1105. $provider = $this->encController->decrypt($encProvider);
  1106. } catch (\Throwable $th) {
  1107. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG000: Ocurrió un error al obtener la ordens.", $th->getMessage(), 500);
  1108. }
  1109. try {
  1110. $user = $this->encController->decrypt($encUser);
  1111. } catch (\Throwable $th) {
  1112. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG001: Ocurrió un error al obtener la ordens.", $th->getMessage(), 500);
  1113. }
  1114. try {
  1115. $getProvider = (array) DB::table('S002V01TPROV')
  1116. ->where('PROV_NUPR', '=', $provider)
  1117. ->first([
  1118. 'PROV_NOCO',
  1119. 'PROV_NOMB',
  1120. 'PROV_APPA',
  1121. 'PROV_APMA',
  1122. 'PROV_CORR',
  1123. 'PROV_LAD1',
  1124. 'PROV_TEL1',
  1125. 'PROV_LAD2',
  1126. 'PROV_TEL2',
  1127. 'PROV_XRFC',
  1128. 'PROV_XTAX',
  1129. 'PROV_CORF',
  1130. 'PROV_TIPO',
  1131. 'PROV_SIWE',
  1132. 'PROV_MEPA',
  1133. 'PROV_USRE',
  1134. 'PROV_FERE',
  1135. 'PROV_USMO',
  1136. 'PROV_FEMO',
  1137. ]);
  1138. } catch (\Throwable $th) {
  1139. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG002: Ocurrió un error al obtener la ordens.", $th->getMessage(), 500);
  1140. }
  1141. try {
  1142. $getProviderReferences = DB::table('S002V01TPRRE')
  1143. ->where('PRRE_NUPR', '=', $provider)
  1144. ->where('PRRE_ESTA', '=', 'Activo')
  1145. ->where('PRRE_NULI', '=', $line)
  1146. ->get([
  1147. 'PRRE_IDRE',
  1148. 'PRRE_EMPR',
  1149. 'PRRE_CORR',
  1150. 'PRRE_LADA',
  1151. 'PRRE_TELE',
  1152. 'PRRE_XRFC',
  1153. 'PRRE_DIRE',
  1154. ]);
  1155. } catch (\Throwable $th) {
  1156. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG003: Ocurrió un error al obtener la ordens.", $th->getMessage(), 500);
  1157. }
  1158. $getProviderReferences = json_decode(json_encode($getProviderReferences), true);
  1159. try {
  1160. $getProviderCondiciones = DB::table('S002V01TPRCN')
  1161. ->where('PRCN_NUPR', '=', $provider)
  1162. ->where('PRCN_ESTA', '=', 'Activo')
  1163. ->where('PRCN_NULI', '=', $line)
  1164. ->get([
  1165. 'PRCN_IDCM',
  1166. 'PRCN_TIPO',
  1167. 'PRCN_INFO',
  1168. ]);
  1169. } catch (\Throwable $th) {
  1170. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG004: Ocurrió un error al obtener la ordens.", $th->getMessage(), 500);
  1171. }
  1172. $getProviderCondiciones = json_decode(json_encode($getProviderCondiciones), true);
  1173. try {
  1174. $getProviderCatalog = DB::table('S002V01TPRCE')
  1175. ->where('PRCE_NUPR', '=', $provider)
  1176. ->where('PRCE_ESTA', '=', 'Activo')
  1177. ->where('PRCE_NULI', '=', $line)
  1178. ->get([
  1179. 'PRCE_IDCE',
  1180. 'PRCE_CATA',
  1181. 'PRCE_DESC',
  1182. 'PRCE_XURL',
  1183. ]);
  1184. } catch (\Throwable $th) {
  1185. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG005: Ocurrió un error al obtener la ordens.", $th->getMessage(), 500);
  1186. }
  1187. $getProviderCatalog = json_decode(json_encode($getProviderCatalog), true);
  1188. try {
  1189. $getProviderContacto = DB::table('S002V01TPRCO')
  1190. ->where('PRCO_NUPR', '=', $provider)
  1191. ->where('PRCO_ESTA', '=', 'Activo')
  1192. ->where('PRCO_NULI', '=', $line)
  1193. ->get([
  1194. 'PRCO_IDCP',
  1195. 'PRCO_NOMB',
  1196. 'PRCO_TIPO',
  1197. 'PRCO_CALL',
  1198. 'PRCO_NUEX',
  1199. 'PRCO_NUIN',
  1200. 'PRCO_COPO',
  1201. 'PRCO_COLO',
  1202. 'PRCO_MUNI',
  1203. 'PRCO_ENTI',
  1204. 'PRCO_PAIS',
  1205. 'PRCO_LAD1',
  1206. 'PRCO_TEL1',
  1207. 'PRCO_LAD2',
  1208. 'PRCO_TEL2',
  1209. 'PRCO_COR1',
  1210. 'PRCO_COR2',
  1211. 'PRCO_OBSE',
  1212. ]);
  1213. } catch (\Throwable $th) {
  1214. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG006: Ocurrió un error al obtener la ordens.", $th->getMessage(), 500);
  1215. }
  1216. $getProviderContacto = json_decode(json_encode($getProviderContacto), true);
  1217. $mpdf = new PDF( [
  1218. 'mode' => 'utf-8',
  1219. 'format' => 'A4',
  1220. 'margin_header' => '3',
  1221. 'margin_top' => '20',
  1222. 'margin_bottom' => '20',
  1223. 'margin_footer' => '2',
  1224. ]);
  1225. $mpdf->SetHTMLHeader('
  1226. <div style="display:flex; align-items: center; text-align: right;">
  1227. <img src="data:image/png;base64,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" width="100">
  1228. </div>
  1229. ');
  1230. $mpdf->WriteHTML('<b>Número de Proveedor:</b> '.$provider);
  1231. $mpdf->WriteHTML('<b>Nombre Comercial:</b> '.$getProvider['PROV_NOCO']);
  1232. $mpdf->WriteHTML('<b>Encargado:</b> '.$getProvider['PROV_NOMB'].' '.$getProvider['PROV_APPA'].' '.$getProvider['PROV_APMA']);
  1233. $mpdf->WriteHTML('<b>Correo Electrónico:</b> '.$getProvider['PROV_CORR']);
  1234. $mpdf->WriteHTML('<b>Teléfono Principal:</b> +'.$getProvider['PROV_LAD1'].' '.$getProvider['PROV_TEL1']);
  1235. if ($getProvider['PROV_LAD2'] != null) {
  1236. $mpdf->WriteHTML('<b>Teléfono Secundario:</b> +'.$getProvider['PROV_LAD2'].' '.$getProvider['PROV_TEL2']);
  1237. }
  1238. if ($getProvider['PROV_XRFC'] != null) {
  1239. $mpdf->WriteHTML('<b>R.F.C.:</b> '.$getProvider['PROV_XRFC']);
  1240. }
  1241. if ($getProvider['PROV_XTAX'] != null) {
  1242. $mpdf->WriteHTML('<b>TAX ID:</b> '.$getProvider['PROV_XTAX']);
  1243. }
  1244. $mpdf->WriteHTML('<b>Regimen Fiscal:</b> '.$getProvider['PROV_CORF']);
  1245. $mpdf->WriteHTML('<b>Tipo de Proveedor:</b> '.$getProvider['PROV_TIPO']);
  1246. $mpdf->WriteHTML('<b>Sitio Web:</b> '.$getProvider['PROV_SIWE']);
  1247. $mpdf->WriteHTML('<hr>');
  1248. $mpdf->WriteHTML('<b>Métodos de Pago Aceptados:</b>');
  1249. $arrMethod = json_decode($getProvider['PROV_MEPA'], true);
  1250. $htmlList = '<ul style="margin: 0;">';
  1251. foreach ($arrMethod as $keyMethod => $isHabilited) {
  1252. if ($isHabilited) {
  1253. $htmlList .= '<li>';
  1254. $htmlList .= $keyMethod;
  1255. $htmlList .= '</li>';
  1256. }
  1257. }
  1258. $htmlList .= '</ul>';
  1259. $mpdf->WriteHTML($htmlList);
  1260. $mpdf->WriteHTML('<hr>');
  1261. $htmlReferences = '<b>Contactos del Proveedor</b><br>
  1262. <table border="1" style="margin-top: 12px;">
  1263. <thead>
  1264. <tr>
  1265. <th style="font-size: 8pt;">No</th>
  1266. <th style="font-size: 8pt;">Nombre Empleado</th>
  1267. <th style="font-size: 8pt;">Dirección</th>
  1268. <th style="font-size: 8pt;">Teléfono 1</th>
  1269. <th style="font-size: 8pt;">Teléfono 2</th>
  1270. <th style="font-size: 8pt;">Correo Electrónico 1</th>
  1271. <th style="font-size: 8pt;">Correo Electrónico 2</th>
  1272. <th style="font-size: 8pt;">Observaciones</th>
  1273. </tr>
  1274. </thead>
  1275. <tbody>';
  1276. foreach ($getProviderContacto as $key => $providerContacto) {
  1277. $htmlReferences .= '<tr>';
  1278. // No
  1279. $htmlReferences .='<td style="font-size: 8pt;">'.$providerContacto['PRCO_IDCP'].'</td>';
  1280. // Nombre Empleado
  1281. $htmlReferences .='<td style="font-size: 8pt;">'.$providerContacto['PRCO_NOMB'].'</td>';
  1282. // Direccion
  1283. $direction = $providerContacto['PRCO_CALL'].' '.$providerContacto['PRCO_NUEX'].' '.$providerContacto['PRCO_NUIN'].' '.$providerContacto['PRCO_COPO'].' '.
  1284. $providerContacto['PRCO_MUNI'].' '.$providerContacto['PRCO_ENTI'].' '.$providerContacto['PRCO_PAIS'];
  1285. $htmlReferences .='<td style="font-size: 8pt;">'.$direction.'</td>';
  1286. // Teléfono 1
  1287. $htmlReferences .='<td style="font-size: 8pt;">+'.$providerContacto['PRCO_LAD1'].' '.$providerContacto['PRCO_TEL1'].'</td>';
  1288. // Teléfono 2
  1289. if ($providerContacto['PRCO_LAD2'] != null) {
  1290. $htmlReferences .='<td style="font-size: 8pt;">+'.$providerContacto['PRCO_LAD2'].' '.$providerContacto['PRCO_TEL2'].'</td>';
  1291. } else {
  1292. $htmlReferences .= '<td>-</td>';
  1293. }
  1294. // Correo 1
  1295. $htmlReferences .='<td style="font-size: 8pt;">'.$providerContacto['PRCO_COR1'].'</td>';
  1296. // Correo 2
  1297. if ($providerContacto['PRCO_COR2'] != null) {
  1298. $htmlReferences .='<td style="font-size: 8pt;">'.$providerContacto['PRCO_COR2'].'</td>';
  1299. } else {
  1300. $htmlReferences .= '<td>-</td>';
  1301. }
  1302. // Observaciones
  1303. if ($providerContacto['PRCO_OBSE'] != null) {
  1304. $htmlReferences .='<td style="font-size: 8pt;">'.$providerContacto['PRCO_OBSE'].'</td>';
  1305. } else {
  1306. $htmlReferences .= '<td>-</td>';
  1307. }
  1308. $htmlReferences .= '</tr>';
  1309. }
  1310. $htmlReferences .= '</tbody></table>';
  1311. $mpdf->WriteHTML($htmlReferences);
  1312. $mpdf->WriteHTML('<hr>');
  1313. $htmlReferences = '<b>Referencias del Proveedor</b><br>
  1314. <table border="1" style="margin-top: 12px;">
  1315. <thead>
  1316. <tr>
  1317. <th style="font-size: 8pt;">No</th>
  1318. <th style="font-size: 8pt;">Empresa</th>
  1319. <th style="font-size: 8pt;">Correo Electrónico</th>
  1320. <th style="font-size: 8pt;">Teléfono</th>
  1321. <th style="font-size: 8pt;">R.F.C.</th>
  1322. <th style="font-size: 8pt;">Dirección</th>
  1323. </tr>
  1324. </thead>
  1325. <tbody>';
  1326. foreach ($getProviderReferences as $key => $providerReferences) {
  1327. $htmlReferences .= '<tr>';
  1328. $htmlReferences .='<td style="font-size: 8pt;">'.$providerReferences['PRRE_IDRE'].'</td>';
  1329. $htmlReferences .='<td style="font-size: 8pt;">'.$providerReferences['PRRE_EMPR'].'</td>';
  1330. $htmlReferences .='<td style="font-size: 8pt;">'.$providerReferences['PRRE_CORR'].'</td>';
  1331. $htmlReferences .='<td style="font-size: 8pt;">+'.$providerReferences['PRRE_LADA'].' '.$providerReferences['PRRE_TELE'].'</td>';
  1332. $htmlReferences .='<td style="font-size: 8pt;">'.$providerReferences['PRRE_XRFC'].'</td>';
  1333. $htmlReferences .='<td style="font-size: 8pt;">'.$providerReferences['PRRE_DIRE'].'</td>';
  1334. $htmlReferences .= '</tr>';
  1335. }
  1336. $htmlReferences .= '</tbody></table>';
  1337. $mpdf->WriteHTML($htmlReferences);
  1338. $mpdf->WriteHTML('<hr>');
  1339. $htmlCondition = '<b>Condiciones del Proveedor</b><br>';
  1340. foreach ($getProviderCondiciones as $key => $providerCondiciones) {
  1341. $htmlCondition .= '<b>Tipo de Condición</b>: '.$providerCondiciones['PRCN_TIPO'];
  1342. $htmlCondition .= '<p>'.$providerCondiciones['PRCN_INFO'].'</p>';
  1343. }
  1344. $mpdf->WriteHTML($htmlCondition);
  1345. $contentFile = $mpdf->Output('', "S");
  1346. $base64File = base64_encode($contentFile);
  1347. try {
  1348. $arrResponse = $this->resourcesController->saveDocument($base64File, 'GEAD','FICHA_PROVEEDOR_'.$provider.'.pdf','IN',$line);
  1349. } catch (\Throwable $th) {
  1350. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG008: Ocurrió un error al obtener la información.", $th->getMessage(), 500);
  1351. }
  1352. if ($arrResponse['error']) {
  1353. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG009: Ocurrió un error al obtener la información.", [], 500);
  1354. }
  1355. try {
  1356. $validateInsert = DB::table('S002V01TPRDO')->insert([
  1357. 'PRDO_NUPR' => $provider,
  1358. 'PRDO_CODU' => $arrResponse['response'],
  1359. 'PRDO_DESC' => 'Ficha',
  1360. 'PRDO_TIPO' => 'IN',
  1361. 'PRDO_NULI' => $line,
  1362. 'PRDO_USRE' => $user,
  1363. 'PRDO_FERE' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
  1364. 'PRDO_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
  1365. ]);
  1366. } catch (\Throwable $th) {
  1367. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG010: Ocurrió un error al ingresar la ficha.", $th->getMessage(), 500);
  1368. }
  1369. if (!$validateInsert) {
  1370. return $this->responseController->makeResponse(true, "ERR_GENERATE_SHEET_REG011: No se pudo ingresar la ficha.", [], 500);
  1371. }
  1372. return $this->responseController->makeResponse(false, "ÉXITO: Ficha Exitosa", $arrResponse['response']);
  1373. }
  1374. public function getArtitlesByProvider($encProvider, $line) {
  1375. DB::beginTransaction();
  1376. // Se obtiene el número del proveedor
  1377. try {
  1378. $provider = $this->encController->decrypt($encProvider);
  1379. } catch (\Throwable $th) {
  1380. DB::rollBack();
  1381. return $this->responseController->makeResponse(true, "ERR_ARTITLES_PROVIDER_GET000: Ocurrió un error al obtener el número del proveedor.", $th->getMessage(), 500);
  1382. }
  1383. // Verifica su existe el proveedor
  1384. try {
  1385. $validateExist = DB::table('S002V01TPROV')
  1386. ->where('PROV_NUPR', '=', $provider)
  1387. ->where('PROV_NULI', '=', $line)
  1388. ->exists();
  1389. } catch (\Throwable $th) {
  1390. DB::rollBack();
  1391. return $this->responseController->makeResponse(true, "ERR_ARTITLES_PROVIDER_GET001: Ocurrió un error al identificar el proveedor.", $th->getMessage(), 500);
  1392. }
  1393. // Valida si existe el proveedor
  1394. if (!$validateExist) {
  1395. DB::rollBack();
  1396. return $this->responseController->makeResponse(true, "ERR_ARTITLES_PROVIDER_GET002: El proveedor no existe", [], 500);
  1397. }
  1398. // Obtiene todos las descripciones de los artículos del proveedor
  1399. try {
  1400. $getDescriptionArtitles = DB::table('S002V01TDEAR')
  1401. ->where('DEAR_NUPR', '=', $provider)
  1402. ->where('DEAR_NULI', '=', $line)
  1403. ->where('DEAR_ESTA', '=', 'Activo')
  1404. ->get([
  1405. 'DEAR_IDDE', # Identificador de la descripción
  1406. 'DEAR_IMAG', # Imagenes de los artículos
  1407. 'DEAR_DESC', # Descripción del artículo
  1408. 'DEAR_CARA', # Características del artículo
  1409. 'DEAR_COWE', # Compra web
  1410. 'DEAR_IDUN', # Identificador del tipo de unidad
  1411. 'DEAR_IDAR', # Identificador del artículo principal
  1412. 'DEAR_USRE', # Usuario de registro
  1413. 'DEAR_FERE', # Fecha de registro
  1414. 'DEAR_USMO', # Usuario de modificación
  1415. 'DEAR_FEMO', # Fecha de modificación
  1416. ]);
  1417. } catch (\Throwable $th) {
  1418. DB::rollBack();
  1419. return $this->responseController->makeResponse(true, "ERR_ARTITLES_PROVIDER_GET003: El proveedor no existe", $th->getMessage(), 500);
  1420. }
  1421. // El resultado pasa a ser un arreglo
  1422. $arrDescriptionArtitles = json_decode(json_encode($getDescriptionArtitles), true);
  1423. $arrDescription = array();
  1424. foreach ($arrDescriptionArtitles as $keyDescription => $descriptionArtitle) {
  1425. // Obtiene las imagenes y las pasa a un arreglo
  1426. $descriptionArtitle['DEAR_IMAG'] = json_decode($descriptionArtitle['DEAR_IMAG']);
  1427. $descriptionArtitle['DEAR_IMAG'] = json_decode($descriptionArtitle['DEAR_IMAG']);
  1428. // Obtiene la información principal del artículo
  1429. try {
  1430. $objArtitle = DB::table('S002V01TARTI')
  1431. ->where('ARTI_IDAR', '=', $descriptionArtitle['DEAR_IDAR'])
  1432. ->where('ARTI_NULI', '=', $line)
  1433. ->where('ARTI_ESTA', '=', 'Activo')
  1434. ->join('S002V01TFAMI', 'ARTI_IDFA', '=', 'FAMI_IDFA')
  1435. ->join('S002V01TSUBF', 'ARTI_IDSU', '=', 'SUBF_IDSU')
  1436. ->first([
  1437. 'ARTI_IDAR', # Identificador del artículo
  1438. 'ARTI_IDFA', # Identificador de la familia del artículo
  1439. 'FAMI_NOMB', # Nombre de la familia del artículo
  1440. 'ARTI_IDSU', # Identificador de la subfamilia del artículo
  1441. 'SUBF_NOMB', # Nombre de la subfamilia del artículo
  1442. 'ARTI_CODI', # Código de barras del artículo
  1443. 'ARTI_NOMB', # Nombre principal del artículo
  1444. // 'ARTI_USRE', # Usuario de registro
  1445. // 'ARTI_FERE', # Fecha de registro
  1446. // 'ARTI_USMO', # Usuario de modificación
  1447. // 'ARTI_FEMO', # Fecha de modificación
  1448. ]);
  1449. } catch (\Throwable $th) {
  1450. DB::rollBack();
  1451. return $this->responseController->makeResponse(true, "ERR_ARTITLES_PROVIDER_GET004: Ocurrió un error al obtener la información del artículo.", $th->getMessage(), 500);
  1452. }
  1453. // La información es guardada en el arreglo de respuesta
  1454. foreach ($objArtitle as $keyArtitle => $artitle) {
  1455. $descriptionArtitle[$keyArtitle] = $artitle;
  1456. }
  1457. // Se obtiene la unidad del artículo
  1458. try {
  1459. $objUnit = DB::table('S002V01TUNID')
  1460. ->where('UNID_IDUN', '=', $descriptionArtitle['DEAR_IDUN'])
  1461. ->where('UNID_NULI', '=', $line)
  1462. ->where('UNID_ESTA', '=', 'Activo')
  1463. ->first([
  1464. 'UNID_IDUN', # Identificador de la unidad
  1465. 'UNID_NOMB', # Nombre de la unidad
  1466. 'UNID_ACRO', # Acrónimo de la unidad
  1467. 'UNID_USRE', # Usuario de registro
  1468. 'UNID_FERE', # Fecha de registro
  1469. 'UNID_USMO', # Usuario de modificación
  1470. 'UNID_FEMO', # Fecha de modificación
  1471. ]);
  1472. } catch (\Throwable $th) {
  1473. DB::rollBack();
  1474. return $this->responseController->makeResponse(true, "ERR_ARTITLES_PROVIDER_GET005: Ocurrió un error al obtener el tipo de unidad.", $th->getMessage(), 500);
  1475. }
  1476. // La información es guardada en el arreglo de respuesta
  1477. $descriptionArtitle['DEAR_IDUN'] = $objUnit;
  1478. // Se obtienen los detalles de la descripción
  1479. try {
  1480. $getDetailsDescription = DB::table('S002V01TINAR')
  1481. ->where('INAR_IDDE', '=', $descriptionArtitle['DEAR_IDDE'])
  1482. ->where('INAR_NULI', '=', $line)
  1483. ->where('INAR_ESTA', '=', 'Activo')
  1484. ->get([
  1485. 'INAR_IDIN', # Identificador de los detalles
  1486. 'INAR_CODI', # Código del artículo
  1487. 'INAR_MODE', # Módelo del artículo
  1488. 'INAR_MONE', # Tipo de moneda
  1489. 'INAR_PREC', # Precio unitario del artículo
  1490. 'INAR_MOMI', # Mónto mínimo
  1491. 'INAR_CARA', # Características
  1492. 'INAR_USRE', # Usuario de registro
  1493. 'INAR_FERE', # Fecha de registro
  1494. 'INAR_USMO', # Usuario de modificación
  1495. 'INAR_FEMO', # Fecha de modificación
  1496. ]);
  1497. } catch (\Throwable $th) {
  1498. DB::rollBack();
  1499. return $this->responseController->makeResponse(true, "ERR_ARTITLES_PROVIDER_GET007: Ocurrió un error al obtener los detalles de la descripción del artículo.", $th->getMessage(), 500);
  1500. }
  1501. // La información es guardada en el arreglo de respuesta
  1502. $descriptionArtitle['DETAILS'] = $getDetailsDescription;
  1503. // Se almacen el arreglo de respuesta en el arreglo principal
  1504. $arrDescription[] = $descriptionArtitle;
  1505. }
  1506. DB::commit(); # Para guardar los cambios en la base de datos
  1507. return $this->responseController->makeResponse(false, "ÉXITO: Consulta exitosa", $arrDescription);
  1508. }
  1509. public function downloadArtitlesByProvider(Request $request) {
  1510. $validator = Validator::make($request->all(), [
  1511. 'PROVIDER' => 'required|string',
  1512. 'USER' => 'required|string',
  1513. 'LINE_NUMBER' => 'required|string',
  1514. 'DOWNLOAD' => 'required|array',
  1515. ]);
  1516. if ($validator->fails()) {
  1517. return $this->responseController->makeResponse(
  1518. true,
  1519. "ERR_DOWNLOAD_ARTITLE_DOW000: Se encontraron uno o más errores.",
  1520. $this->responseController->makeErrors($validator->errors()->messages()),
  1521. 401
  1522. );
  1523. }
  1524. $responseData = $request->all();
  1525. try {
  1526. $user = $this->encController->decrypt($responseData['USER']);
  1527. } catch (\Throwable $th) {
  1528. DB::rollBack();
  1529. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW001: No se pudo obtener los datos del usuario", $th->getMessage(), 500);
  1530. }
  1531. // Verifica su existe el proveedor
  1532. try {
  1533. $validateExist = DB::table('S002V01TPROV')->where('PROV_NUPR', '=', $responseData['PROVIDER'])->where('PROV_NULI', '=', $responseData['LINE_NUMBER'])->exists();
  1534. } catch (\Throwable $th) {
  1535. DB::rollBack();
  1536. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW002: Ocurrió un error al identificar el proveedor.", $th->getMessage(), 500);
  1537. }
  1538. // Valida si existe el proveedor
  1539. if (!$validateExist) {
  1540. DB::rollBack();
  1541. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW003: El proveedor no existe", [], 500);
  1542. }
  1543. $arrDescriptionId = $responseData['DOWNLOAD'];
  1544. $arrDataArtitles = array();
  1545. foreach ($arrDescriptionId as $keyId => $idDescription) {
  1546. // Obtiene todos las descripciones de los artículos del proveedor
  1547. try {
  1548. $getDescriptionArtitles = DB::table('S002V01TDEAR')
  1549. ->where('DEAR_IDDE', '=', $idDescription)
  1550. ->where('DEAR_NUPR', '=', $responseData['PROVIDER'])
  1551. ->where('DEAR_NULI', '=', $responseData['LINE_NUMBER'])
  1552. ->where('DEAR_ESTA', '=', 'Activo')
  1553. ->first([
  1554. 'DEAR_IDDE', # Identificador de la descripción
  1555. 'DEAR_IMAG', # Imagenes de los artículos
  1556. 'DEAR_DESC', # Descripción del artículo
  1557. 'DEAR_CARA', # Características del artículo
  1558. 'DEAR_COWE', # Compra web
  1559. 'DEAR_IDUN', # Identificador del tipo de unidad
  1560. 'DEAR_IDAR', # Identificador del artículo principal
  1561. 'DEAR_USRE', # Usuario de registro
  1562. 'DEAR_FERE', # Fecha de registro
  1563. 'DEAR_USMO', # Usuario de modificación
  1564. 'DEAR_FEMO', # Fecha de modificación
  1565. ]);
  1566. } catch (\Throwable $th) {
  1567. DB::rollBack();
  1568. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW004: El proveedor no existe", $th->getMessage(), 500);
  1569. }
  1570. $arrDescriptionArtitles = (array) $getDescriptionArtitles;
  1571. // Obtiene la información principal del artículo
  1572. try {
  1573. $objArtitle = DB::table('S002V01TARTI')
  1574. ->where('ARTI_IDAR', '=', $arrDescriptionArtitles['DEAR_IDAR'])
  1575. ->where('ARTI_NULI', '=', $responseData['LINE_NUMBER'])
  1576. ->where('ARTI_ESTA', '=', 'Activo')
  1577. ->join('S002V01TFAMI', 'ARTI_IDFA', '=', 'FAMI_IDFA')
  1578. ->join('S002V01TSUBF', 'ARTI_IDSU', '=', 'SUBF_IDSU')
  1579. ->first([
  1580. 'ARTI_IDAR', # Identificador del artículo
  1581. 'ARTI_IDFA', # Identificador de la familia del artículo
  1582. 'FAMI_NOMB', # Nombre de la familia del artículo
  1583. 'ARTI_IDSU', # Identificador de la subfamilia del artículo
  1584. 'SUBF_NOMB', # Nombre de la subfamilia del artículo
  1585. 'ARTI_CODI', # Código de barras del artículo
  1586. 'ARTI_NOMB', # Nombre principal del artículo
  1587. ]);
  1588. } catch (\Throwable $th) {
  1589. DB::rollBack();
  1590. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW005: Ocurrió un error al obtener la información del artículo.", $th->getMessage(), 500);
  1591. }
  1592. $objArtitle = (array) $objArtitle;
  1593. // La información es guardada en el arreglo de respuesta
  1594. foreach ($objArtitle as $keyArtitle => $artitle) {
  1595. $arrDescriptionArtitles[$keyArtitle] = $artitle;
  1596. }
  1597. // Se obtiene la unidad del artículo
  1598. try {
  1599. $objUnit = DB::table('S002V01TUNID')
  1600. ->where('UNID_IDUN', '=', $arrDescriptionArtitles['DEAR_IDUN'])
  1601. ->where('UNID_NULI', '=', $responseData['LINE_NUMBER'])
  1602. ->where('UNID_ESTA', '=', 'Activo')
  1603. ->first([
  1604. 'UNID_IDUN', # Identificador de la unidad
  1605. 'UNID_NOMB', # Nombre de la unidad
  1606. 'UNID_ACRO', # Acrónimo de la unidad
  1607. ]);
  1608. } catch (\Throwable $th) {
  1609. DB::rollBack();
  1610. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW006: Ocurrió un error al obtener el tipo de unidad.", $th->getMessage(), 500);
  1611. }
  1612. // La información es guardada en el arreglo de respuesta
  1613. $arrDescriptionArtitles['DEAR_IDUN'] = $objUnit;
  1614. // Se obtienen los detalles de la descripción
  1615. try {
  1616. $getDetailsDescription = DB::table('S002V01TINAR')
  1617. ->where('INAR_IDDE', '=', $idDescription)
  1618. ->where('INAR_NULI', '=', $responseData['LINE_NUMBER'])
  1619. ->where('INAR_ESTA', '=', 'Activo')
  1620. ->get([
  1621. 'INAR_IDIN', # Identificador de los detalles
  1622. 'INAR_CODI', # Código del artículo
  1623. 'INAR_MODE', # Módelo del artículo
  1624. 'INAR_MONE', # Tipo de moneda
  1625. 'INAR_PREC', # Precio unitario del artículo
  1626. 'INAR_MOMI', # Mónto mínimo
  1627. 'INAR_CARA', # Características
  1628. 'INAR_USRE', # Usuario de registro
  1629. 'INAR_FERE', # Fecha de registro
  1630. 'INAR_USMO', # Usuario de modificación
  1631. 'INAR_FEMO', # Fecha de modificación
  1632. ]);
  1633. } catch (\Throwable $th) {
  1634. DB::rollBack();
  1635. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW007: Ocurrió un error al obtener los detalles de la descripción del artículo.", $th->getMessage(), 500);
  1636. }
  1637. $arrDetailsDescription = json_decode(json_encode($getDetailsDescription), true);
  1638. $arrDescriptionArtitles['DETAILS'] = $arrDetailsDescription;
  1639. $arrDataArtitles[] = $arrDescriptionArtitles;
  1640. }
  1641. // Se inicializa el nombre del documento
  1642. $nameDocument = "CONTENT_ARTITLE_BY_".$responseData['PROVIDER'].".xlsx";
  1643. // Se crea el documento y se obtiene el base64 del documento
  1644. $base64Document = $this->createDocument($arrDataArtitles);
  1645. // Se guarda el documento y se genera el código del documento
  1646. $arrResponseDocument = $this->resourcesController->saveDocument($base64Document, 'GEAD', $nameDocument, 'IN', $responseData['LINE_NUMBER']);
  1647. if ( $arrResponseDocument['error'] ) {
  1648. DB::rollBack();
  1649. return $this->responseController->makeResponse(true, 'ERR_DOWNLOAD_ARTITLE_DOW008:'.$arrResponseDocument['msg'], $arrResponseDocument['response'], 500);
  1650. }
  1651. // Se obtiene el código del documento
  1652. $codeDocument = $arrResponseDocument['response'];
  1653. try {
  1654. $validaeInsert = DB::table('S002V01TPRDO')->insert([
  1655. 'PRDO_NUPR' => $responseData['PROVIDER'],
  1656. 'PRDO_CODU' => $codeDocument,
  1657. 'PRDO_TIPO' => 'IN',
  1658. 'PRDO_DESC' => 'GENERACIÓN DE DOCUMENTO DE ARTÍCULOS POR PROVEEDOR',
  1659. 'PRDO_NULI' => $responseData['LINE_NUMBER'],
  1660. 'PRDO_USRE' => $user,
  1661. 'PRDO_FERE' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
  1662. 'PRDO_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
  1663. ]);
  1664. } catch (\Throwable $th) {
  1665. DB::rollBack();
  1666. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW009: Ocurrió un error al registrar el documento.", $th->getMessage(), 500);
  1667. }
  1668. if (!$validaeInsert) {
  1669. DB::rollBack();
  1670. return $this->responseController->makeResponse(true, "ERR_DOWNLOAD_ARTITLE_DOW010: No se pudo registrar el documento en la base de datos", [], 500);
  1671. }
  1672. DB::commit(); # Para guardar los cambios en la base de datos
  1673. return $this->responseController->makeResponse(false, "ÉXITO: Se genero correctamente.", $codeDocument);
  1674. }
  1675. public function uploadArtitlesByProvider(Request $request) {
  1676. $validator = Validator::make($request->all(), [
  1677. 'PROVIDER' => 'required|string',
  1678. 'USER' => 'required|string',
  1679. 'LINE_NUMBER' => 'required|string',
  1680. 'DOCUMENT' => 'required|string',
  1681. ]);
  1682. if ($validator->fails()) {
  1683. return $this->responseController->makeResponse(
  1684. true,
  1685. "ERR_UPLOAD_ARTITLE_UPL000: Se encontraron uno o más errores.",
  1686. $this->responseController->makeErrors($validator->errors()->messages()),
  1687. 401
  1688. );
  1689. }
  1690. DB::beginTransaction();
  1691. $responseData = $request->all();
  1692. try {
  1693. $user = $this->encController->decrypt($responseData['USER']);
  1694. } catch (\Throwable $th) {
  1695. DB::rollBack();
  1696. return $this->responseController->makeResponse(true, "ERR_UPLOAD_ARTITLE_UPL001: No se pudo obtener los datos del usuario", $th->getMessage(), 500);
  1697. }
  1698. $nameDocument = "UPLOAD_".$responseData['PROVIDER']."_".date('YmdHms').".xlsx";
  1699. // Se guarda el documento y se genera el código del documento
  1700. $arrResponseDocument = $this->resourcesController->saveDocument($responseData['DOCUMENT'], 'GEAD', $nameDocument, 'IN', $responseData['LINE_NUMBER']);
  1701. if ( $arrResponseDocument['error'] ) {
  1702. DB::rollBack();
  1703. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL002:'.$arrResponseDocument['msg'], $arrResponseDocument['response'], 500);
  1704. }
  1705. // Se obtiene el código del documento
  1706. $codeDocument = $arrResponseDocument['response'];
  1707. // Se obtiene la ruta en donde se guardará el archivo
  1708. $routeSaveDocument = "/app/public/GEAD/";
  1709. // Se obtiene la ruta completa del archivo a guardar
  1710. $pathRoute = storage_path().$routeSaveDocument.$codeDocument;
  1711. if(!file_exists($pathRoute)){
  1712. DB::rollBack();
  1713. return $this->responseController->makeResponse(true, "ERR_UPLOAD_ARTITLE_UPL003: No se pudo obtener el documento.", [], 500);
  1714. }
  1715. $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx;
  1716. $spreadsheet = $reader->load($pathRoute);
  1717. $sheet = $spreadsheet->getSheetByName('ART');
  1718. $maxRow = $sheet->getHighestRow();
  1719. $maxColumn = $sheet->getHighestColumn();
  1720. try {
  1721. $arrDataArtitle = array();
  1722. for ($positionRow=2; $positionRow <= $maxRow; $positionRow++) {
  1723. $arrContentRow = array();
  1724. for ($positionColumn = 0; $positionColumn <= array_search($maxColumn, $this->arrAlphabet); $positionColumn++) {
  1725. $data = $sheet->getCell($this->arrAlphabet[$positionColumn].$positionRow)->getValue();
  1726. // $code = $this->arrHeader[array_search($this->arrAlphabet[$positionColumn], $this->arrAlphabet)]['CODE'];
  1727. $infoHeader = $this->arrHeader[array_search($this->arrAlphabet[$positionColumn], $this->arrAlphabet)];
  1728. $data = trim($data);
  1729. if ($data == '' && $infoHeader['OBLIGATORY']) {
  1730. $position = $this->arrAlphabet[$positionColumn].$positionRow;
  1731. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL004: El campo "'.$position.'" de la hoja ART es obligatorio.', [], 500);
  1732. } else if ($data == '') {
  1733. $data = null;
  1734. }
  1735. $arrContentRow[$infoHeader['CODE']] = $data;
  1736. }
  1737. $arrDataArtitle[] = $arrContentRow;
  1738. }
  1739. } catch (\Throwable $th) {
  1740. DB::rollBack();
  1741. return $this->responseController->makeResponse(true, "ERR_UPLOAD_ARTITLE_UPL005: No se pudieron obtener los datos. Verifique que el formato de su documento sea correcto.", $th->getMessage(), 500);
  1742. }
  1743. $arrIdDetails = array();
  1744. foreach ($arrDataArtitle as $keyArtitle => $artitle) {
  1745. foreach ($this->arrHeader as $keyHeader => $header) {
  1746. if (!array_key_exists($header['CODE'], $artitle)) {
  1747. DB::rollBack();
  1748. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL006: El campo "'.$header['COLUMN'].'" no existe en los encabezados.', [], 500);
  1749. }
  1750. }
  1751. try {
  1752. $validateExistArtitle = DB::table('S002V01TARTI')
  1753. ->where('ARTI_IDAR', '=', $artitle['ARTI_IDAR'])
  1754. ->where('ARTI_NULI', '=', $responseData['LINE_NUMBER'])
  1755. ->where('ARTI_ESTA', '=', 'Activo')
  1756. ->exists();
  1757. } catch (\Throwable $th) {
  1758. DB::rollBack();
  1759. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL007: Ocurrió un error al validar los artículos', $th->getMessage(), 500);
  1760. }
  1761. if (!$validateExistArtitle) {
  1762. DB::rollBack();
  1763. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL008: El artículo con el número '.$artitle['ARTI_IDAR'].' no existe.', [], 500);
  1764. }
  1765. try {
  1766. $validateExistDetails = (array) DB::table('S002V01TDEAR')
  1767. ->where('DEAR_IDAR', '=', $artitle['ARTI_IDAR'])
  1768. ->where('DEAR_NUPR', '=', $responseData['PROVIDER'])
  1769. ->where('DEAR_ESTA', '=', 'Activo')
  1770. ->exists();
  1771. } catch (\Throwable $th) {
  1772. DB::rollBack();
  1773. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL009: Ocurrió un error al validar la descripción', $th->getMessage(), 500);
  1774. }
  1775. if (!$validateExistDetails) {
  1776. DB::rollBack();
  1777. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL010: La descripción del artículo no pudo ser encontrada.', [], 500);
  1778. }
  1779. // $arrIdDetails[] = $arrDescription['DEAR_IDDE'];
  1780. try {
  1781. $arrFamily = (array) DB::table('S002V01TFAMI')
  1782. ->where('FAMI_NULI', '=', $responseData['LINE_NUMBER'])
  1783. ->where('FAMI_ESTA', '=', 'Activo')
  1784. ->where('FAMI_NOMB', '=', $artitle['FAMI_NOMB'])
  1785. ->first();
  1786. } catch (\Throwable $th) {
  1787. DB::rollBack();
  1788. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL011: Ocurrió un error al validar la descripción.', $th->getMessage(), 500);
  1789. }
  1790. if (count($arrFamily) == 0) {
  1791. DB::rollBack();
  1792. $indexHeader = array_search('FAMI_NOMB', array_column($this->arrHeader, 'CODE'));
  1793. $header = $this->arrHeader[$indexHeader]['COLUMN'];
  1794. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL012: El valor del campo "'.$header.'" no es válido.', [], 500);
  1795. }
  1796. try {
  1797. $arrSubfamily = (array) DB::table('S002V01TSUBF')
  1798. ->where('SUBF_NULI', '=', $responseData['LINE_NUMBER'])
  1799. ->where('SUBF_ESTA', '=', 'Activo')
  1800. ->where('SUBF_NOMB', '=', $artitle['SUBF_NOMB'])
  1801. ->first();
  1802. } catch (\Throwable $th) {
  1803. DB::rollBack();
  1804. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL013: Ocurrió un error al validar la descripción.', $th->getMessage(), 500);
  1805. }
  1806. if (count($arrSubfamily) == 0) {
  1807. DB::rollBack();
  1808. $indexHeader = array_search('SUBF_NOMB', array_column($this->arrHeader, 'CODE'));
  1809. $header = $this->arrHeader[$indexHeader]['COLUMN'];
  1810. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL014: El valor del campo "'.$header.'" no es válido.', [], 500);
  1811. }
  1812. try {
  1813. $validateUpdate = DB::table('S002V01TARTI')
  1814. ->where('ARTI_IDAR', '=', $artitle['ARTI_IDAR'])
  1815. ->where('ARTI_NULI', '=', $responseData['LINE_NUMBER'])
  1816. ->update([
  1817. 'ARTI_IDFA' => $arrFamily['FAMI_IDFA'],
  1818. 'ARTI_IDSU' => $arrSubfamily['SUBF_IDSU'],
  1819. 'ARTI_CODI' => $artitle['ARTI_CODI'],
  1820. 'ARTI_NOMB' => $artitle['ARTI_NOMB'],
  1821. 'ARTI_USMO' => $user,
  1822. 'ARTI_FEMO' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
  1823. ]);
  1824. } catch (\Throwable $th) {
  1825. DB::rollBack();
  1826. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL015: Ocurrió un error al actualizar los artículos.', $th->getMessage(), 500);
  1827. }
  1828. if (!$validateUpdate) {
  1829. DB::rollBack();
  1830. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL016: No se pudieron actualizar los artículos.', [], 500);
  1831. }
  1832. if ($artitle['DEAR_COWE'] == 'Si') {
  1833. $webPurchase = 1;
  1834. }else if ($artitle['DEAR_COWE'] == 'No') {
  1835. $webPurchase = 0;
  1836. } else {
  1837. DB::rollBack();
  1838. $indexHeader = array_search('DEAR_COWE', array_column($this->arrHeader, 'CODE'));
  1839. $header = $this->arrHeader[$indexHeader]['COLUMN'];
  1840. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL017: El valor del campo "'.$header.'" no es válido.', [], 500);
  1841. }
  1842. try {
  1843. $arrUnid = (array) DB::table('S002V01TUNID')
  1844. ->where('UNID_NULI', '=', $responseData['LINE_NUMBER'])
  1845. ->where('UNID_ESTA', '=', 'Activo')
  1846. ->where('UNID_NOMB', '=', $artitle['DEAR_IDUN'])
  1847. ->first();
  1848. } catch (\Throwable $th) {
  1849. DB::rollBack();
  1850. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL018: Ocurrió un error al obtener las unidades.', $th->getMessage(), 500);
  1851. }
  1852. if (count($arrUnid) == 0) {
  1853. DB::rollBack();
  1854. $indexHeader = array_search('DEAR_IDUN', array_column($this->arrHeader, 'CODE'));
  1855. $header = $this->arrHeader[$indexHeader]['COLUMN'];
  1856. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL019: El valor del campo "'.$header.'" no es válido.', [], 500);
  1857. }
  1858. try {
  1859. $validateUpdate = DB::table('S002V01TDEAR')
  1860. ->where('DEAR_NUPR', '=', $responseData['PROVIDER'])
  1861. ->where('DEAR_IDAR', '=', $artitle['ARTI_IDAR'])
  1862. ->where('DEAR_ESTA', '=', 'Activo')
  1863. ->where('DEAR_NULI', '=', $responseData['LINE_NUMBER'])
  1864. ->update([
  1865. 'DEAR_DESC' => $artitle['DEAR_DESC'],
  1866. 'DEAR_CARA' => $artitle['DEAR_CARA'],
  1867. 'DEAR_COWE' => $webPurchase,
  1868. 'DEAR_IDUN' => $arrUnid['UNID_IDUN'],
  1869. 'DEAR_USMO' => $user,
  1870. 'DEAR_FEMO' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
  1871. 'DEAR_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
  1872. ]);
  1873. } catch (\Throwable $th) {
  1874. DB::rollBack();
  1875. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL020: Ocurrió un error al actualizar las descripciones de los artículos.', $th->getMessage(), 500);
  1876. }
  1877. if (!$validateUpdate) {
  1878. DB::rollBack();
  1879. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL021: No se pudieron actualizar las descripciones de los.', [], 500);
  1880. }
  1881. $arrIdDetails[] = $artitle['ARTI_IDAR'];
  1882. }
  1883. foreach ($arrIdDetails as $idDetails) {
  1884. $readerDetails = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx;
  1885. $spreadsheet = $readerDetails->load($pathRoute);
  1886. $sheet = $spreadsheet->getSheetByName('ARTDET-'.$idDetails);
  1887. $maxRow = $sheet->getHighestRow();
  1888. $maxColumn = $sheet->getHighestColumn();
  1889. try {
  1890. $arrDataDetails = array();
  1891. for ($positionRow=2; $positionRow <= $maxRow; $positionRow++) {
  1892. $arrContentRow = array();
  1893. for ($positionColumn = 0; $positionColumn <= array_search($maxColumn, $this->arrAlphabet); $positionColumn++) {
  1894. $data = $sheet->getCell($this->arrAlphabet[$positionColumn].$positionRow)->getValue();
  1895. $infoHeader = $this->arrHeaderDetails[array_search($this->arrAlphabet[$positionColumn], $this->arrAlphabet)];
  1896. $data = trim($data);
  1897. if ($data == '' && $infoHeader['OBLIGATORY']) {
  1898. $position = $this->arrAlphabet[$positionColumn].$positionRow;
  1899. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL022: El campo "'.$position.'" de la hoja ARTDET-'.$idDetails.' es obligatorio.', [], 500);
  1900. } else if ($data == '') {
  1901. $data = null;
  1902. }
  1903. $arrContentRow[$infoHeader['CODE']] = $data;
  1904. }
  1905. $arrDataDetails[] = $arrContentRow;
  1906. }
  1907. } catch (\Throwable $th) {
  1908. DB::rollBack();
  1909. return $this->responseController->makeResponse(true, "ERR_UPLOAD_ARTITLE_UPL023: No se pudieron obtener los datos. Verifique que el formato de su documento sea correcto.", $th->getMessage(), 500);
  1910. }
  1911. foreach ($arrDataDetails as $keyDetails => $details) {
  1912. foreach ($this->arrHeaderDetails as $keyHeader => $header) {
  1913. if (!array_key_exists($header['CODE'], $details)) {
  1914. DB::rollBack();
  1915. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL024: El campo "'.$header['COLUMN'].'" no existe en los encabezados.', [], 500);
  1916. }
  1917. }
  1918. try {
  1919. $validateDetails = DB::table('S002V01TINAR')
  1920. ->where('INAR_IDIN', '=', $details['INAR_IDIN'])
  1921. ->where('INAR_ESTA', '=', 'Activo')
  1922. ->where('INAR_NULI', '=', $responseData['LINE_NUMBER'])
  1923. ->exists();
  1924. } catch (\Throwable $th) {
  1925. DB::rollBack();
  1926. return $this->responseController->makeResponse(true, "ERR_UPLOAD_ARTITLE_UPL025: No se pudieron obtener los datos. Verifique que el formato de su documento sea correcto.", $th->getMessage(), 500);
  1927. }
  1928. if (!$validateDetails) {
  1929. DB::rollBack();
  1930. $indexHeader = array_search('INAR_IDIN', array_column($this->arrHeaderDetails, 'CODE'));
  1931. $header = $this->arrHeaderDetails[$indexHeader]['COLUMN'];
  1932. $position = $this->arrHeaderDetails[$indexHeader]['POSITION'];
  1933. $errorPosition = $position.$keyDetails+1;
  1934. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL026: El valor del campo "'.$header.'" no es válido.', [], 500);
  1935. }
  1936. try {
  1937. $validateUpdate = DB::table('S002V01TINAR')
  1938. ->where('INAR_IDIN', '=', $details['INAR_IDIN'])
  1939. ->where('INAR_NULI', '=', $responseData['LINE_NUMBER'])
  1940. ->where('INAR_ESTA', '=', 'Activo')
  1941. ->update([
  1942. 'INAR_CODI' => $details['INAR_CODI'],
  1943. 'INAR_MODE' => $details['INAR_MODE'],
  1944. 'INAR_MONE' => $details['INAR_MONE'],
  1945. 'INAR_PREC' => $details['INAR_PREC'],
  1946. 'INAR_MOMI' => $details['INAR_MOMI'],
  1947. 'INAR_CARA' => $details['INAR_CARA'],
  1948. 'INAR_USMO' => $user,
  1949. 'INAR_FEMO' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
  1950. 'INAR_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
  1951. ]
  1952. );
  1953. } catch (\Throwable $th) {
  1954. DB::rollBack();
  1955. return $this->responseController->makeResponse(true, "ERR_UPLOAD_ARTITLE_UPL027: Ocurrió un error al actualizar los detalles del artículo.", $th->getMessage(), 500);
  1956. }
  1957. if (!$validateUpdate) {
  1958. DB::rollBack();
  1959. return $this->responseController->makeResponse(true, 'ERR_UPLOAD_ARTITLE_UPL028: No se pudo actualizar los detalles del artículo.', [], 500);
  1960. }
  1961. }
  1962. }
  1963. DB::commit();
  1964. return $this->responseController->makeResponse(false, "ÉXITO: Actualización Exitosa");
  1965. }
  1966. private function createDocument($arrDescription) {
  1967. // Se inicializa el archivo xlsx
  1968. $spreadsheet = new Spreadsheet();
  1969. // Se crea la primera hoja donde se encontraran todos los artículos del proveedor
  1970. $activeWorksheet = $spreadsheet->getActiveSheet()->setTitle("ART");
  1971. // Se colocan los encabezados de la tabla
  1972. $positionColumn = 0; # Posición de la columna (Empieza en 0 debído al arreglo del abecedario el cual corresponde a la letra A)
  1973. // Se itean la información del encabezado
  1974. foreach ($this->arrHeader as $keyArtitle => $header) {
  1975. // Se ingresa el encabezado en la hoja
  1976. $activeWorksheet->setCellValue($this->arrAlphabet[$positionColumn]."1", $header['COLUMN']);
  1977. // Se incrementa la posición para la siguiente columna
  1978. $positionColumn++;
  1979. }
  1980. // Se ingresa la información de los artículos
  1981. $positionRow = 2; # Posición de la fila (Empieza en 2 debído a que la posición 1 ya la tomó la información del encabezado)
  1982. // Se iteran los artículos del proveedor
  1983. foreach ($arrDescription as $keyDescription => $arrArtitle) {
  1984. $positionColumn = 0; # Siempre se inicializa en 0 por cada información de los artículos para que vuelva a comenzar en la columna A
  1985. // Se itera el objeto que tiene la información del artículo
  1986. foreach ($this->arrHeader as $keyHeader => $header) {
  1987. // Se verifica que el campo obtenido se encuentre en la lista del encabezado
  1988. // Se hace de esta manera para que se ordenen los campos de acuerdo al ordenamiento de los encabezados
  1989. if(array_key_exists($header['CODE'], $arrArtitle)){
  1990. if ($header['CODE'] == 'DEAR_COWE') {
  1991. $arrArtitle[$header['CODE']] = $arrArtitle[$header['CODE']] == 0 ? 'No':'Si';
  1992. }
  1993. if ($header['CODE'] == 'DEAR_IDUN') {
  1994. $arrArtitle[$header['CODE']] = $arrArtitle[$header['CODE']]->UNID_NOMB;
  1995. }
  1996. // Se ingresa la información
  1997. $activeWorksheet->setCellValue($this->arrAlphabet[$positionColumn].$positionRow, $arrArtitle[$header['CODE']]);
  1998. // Se incrementa la posición para la siguiente columna
  1999. $positionColumn++;
  2000. }
  2001. }
  2002. // Al terminar de procesar toda la información, la posición de la fila se incrementa para que pase a la siguiente fila
  2003. $positionRow++;
  2004. // Se verifica que la información obtenida tenga detalles
  2005. if (count($arrArtitle['DETAILS']) > 0) {
  2006. // En caso de ser verdadero, se crea una nueva hoja
  2007. $spreadsheet->createSheet();
  2008. // Se selecciona para trabajar ahora en esa hoja nueva
  2009. $spreadsheet->setActiveSheetIndex($keyDescription + 1);
  2010. // Se ingresa el nombre de la hoja, que es referente a su información perteneciente
  2011. $activeWorksheetDetails = $spreadsheet->getActiveSheet()->setTitle('ARTDET-'.$arrArtitle['ARTI_IDAR']);
  2012. // Se ingresan los encabezados en la nueva hoja
  2013. $positionColumnDetails = 0; # Posición de la columna de los detalles (Empieza en 0 debído al arreglo del abecedario el cual corresponde a la letra A)
  2014. // Se itean la información del encabezado de los detalles
  2015. foreach ($this->arrHeaderDetails as $keyHeaderDetails => $headerDetails) {
  2016. // Se ingresa el encabezado en la hoja de los detalles
  2017. $activeWorksheetDetails->setCellValue($this->arrAlphabet[$positionColumnDetails]."1", $headerDetails['COLUMN']);
  2018. // Se incrementa la posición para la siguiente columna de los detalles
  2019. $positionColumnDetails++;
  2020. }
  2021. // Se ingresa la información de los artículos
  2022. $positionRowDetails = 2; # Posición de la fila de los detalles (Empieza en 2 debído a que la posición 1 ya la tomó la información del encabezado de los detalles)
  2023. // Se itera el objeto que tiene la información del artículo
  2024. foreach ($arrArtitle['DETAILS'] as $key => $details) {
  2025. $positionColumnDetails = 0; # Siempre se inicializa en 0 por cada información de los detalles para que vuelva a comenzar en la columna A
  2026. // Se itera el objeto que tiene la información de los detalles
  2027. foreach ($this->arrHeaderDetails as $keyHeaderDetails => $headerDetails) {
  2028. // Se verifica que el campo obtenido se encuentre en la lista del encabezado de los detalles
  2029. // Se hace de esta manera para que se ordenen los campos de acuerdo al ordenamiento de los encabezados
  2030. if(array_key_exists($headerDetails['CODE'], $details)){
  2031. // Se ingresan los detalles
  2032. $activeWorksheetDetails->setCellValue($this->arrAlphabet[$positionColumnDetails].$positionRowDetails, $details[$headerDetails['CODE']]);
  2033. // Se incrementa la posición para la siguiente columna
  2034. $positionColumnDetails++;
  2035. }
  2036. }
  2037. // Al terminar de procesar toda la información, la posición de la fila se incrementa para que pase a la siguiente fila
  2038. $positionRowDetails++;
  2039. }
  2040. // Se inicializan las posiciones iniciales y finales
  2041. $inicialPositionDetails = "A1";
  2042. $finalPositionDetails = $this->arrAlphabet[$positionColumnDetails-1].$positionRowDetails-1;
  2043. // Se inicializa el formato de la tabla
  2044. $table = new Table("$inicialPositionDetails:$finalPositionDetails", 'Table'.$arrArtitle['ARTI_IDAR']);
  2045. // Se inicializa los estilos de la tabla
  2046. $tableStyle = new TableStyle();
  2047. // Se ingresa el tipo de tabla
  2048. $tableStyle->setTheme(TableStyle::TABLE_STYLE_MEDIUM10);
  2049. // Se ingresa el estilo en la tabla
  2050. $tableStyle->setShowRowStripes(true);
  2051. $table->setStyle($tableStyle);
  2052. $activeWorksheetDetails->addTable($table);
  2053. // Se ajustan las dimensiones de la hoja de detalles
  2054. $positionColumnDetails = 0; # Posición de la columna (Empieza en 0 debído al arreglo del abecedario el cual corresponde a la letra A)
  2055. // Se iteran la información del encabezado de los detalles
  2056. foreach ($this->arrHeaderDetails as $keyHeaderDetails => $headerDetails) {
  2057. if ($headerDetails['CODE'] == 'INAR_CARA') {
  2058. $activeWorksheetDetails->getColumnDimension($this->arrAlphabet[$positionColumnDetails])->setAutoSize(true);
  2059. $activeWorksheetDetails->getStyle($this->arrAlphabet[$positionColumnDetails])->getAlignment()->setWrapText(true);
  2060. } else {
  2061. $activeWorksheetDetails->getColumnDimension($this->arrAlphabet[$positionColumnDetails])->setAutoSize(true);
  2062. }
  2063. // Las columnas son auto ajustadas
  2064. // Se incrementa la posición para la siguiente columna
  2065. $positionColumnDetails++;
  2066. }
  2067. }
  2068. }
  2069. // Se inicializan las posiciones iniciales y finales
  2070. $inicialPosition = "A1";
  2071. $finalPosition = $this->arrAlphabet[$positionColumn-1].$positionRow-1;
  2072. // Se inicializa el formato de la tabla
  2073. $table = new Table("$inicialPosition:$finalPosition", 'Table1');
  2074. // Se inicializa los estilos de la tabla
  2075. $tableStyle = new TableStyle();
  2076. // Se ingresa el tipo de tabla
  2077. $tableStyle->setTheme(TableStyle::TABLE_STYLE_MEDIUM8);
  2078. // Se ingresa el estilo en la tabla
  2079. $tableStyle->setShowRowStripes(true);
  2080. $table->setStyle($tableStyle);
  2081. $activeWorksheet->addTable($table);
  2082. // Se ajustan las dimensiones de la hoja de los artículos
  2083. $positionColumn = 0; # Posición de la columna (Empieza en 0 debído al arreglo del abecedario el cual corresponde a la letra A)
  2084. // Se iteran la información del encabezado
  2085. foreach ($this->arrHeader as $keyHeader => $header) {
  2086. if ($header['CODE'] == 'DEAR_DESC' || $header['CODE'] == 'DEAR_CARA') {
  2087. // Si se obtienen las siguientes columnas, entonces tendrá 40 de dimensión
  2088. $activeWorksheet->getColumnDimension($this->arrAlphabet[$positionColumn])->setWidth(40);
  2089. $activeWorksheet->getStyle($this->arrAlphabet[$positionColumn])->getAlignment()->setWrapText(true);
  2090. } else {
  2091. // Las columnas son auto ajustadas
  2092. $activeWorksheet->getColumnDimension($this->arrAlphabet[$positionColumn])->setAutoSize(true);
  2093. }
  2094. // Se incrementa la posición para la siguiente columna
  2095. $positionColumn++;
  2096. }
  2097. $writer = new Xlsx($spreadsheet);
  2098. ob_start();
  2099. $writer->save('php://output');
  2100. $base64 = base64_encode(ob_get_clean());
  2101. return $base64;
  2102. // $validate = \File::put( storage_path() . '/test.xlsx', base64_decode($base64) );
  2103. }
  2104. }