@zauru-sdk/utils 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/index.d.ts +23 -2
  3. package/dist/index.js +23 -2
  4. package/dist/zauru/automatic-number.utils.d.ts +9 -0
  5. package/dist/zauru/automatic-number.utils.js +24 -0
  6. package/dist/zauru/bitacora-edicion-masiva.utils.d.ts +23 -0
  7. package/dist/zauru/bitacora-edicion-masiva.utils.js +50 -0
  8. package/dist/zauru/bundles.utils.d.ts +39 -0
  9. package/dist/zauru/bundles.utils.js +160 -0
  10. package/dist/zauru/cases.utils.d.ts +9 -0
  11. package/dist/zauru/cases.utils.js +17 -0
  12. package/dist/zauru/consolidated-history.utils.d.ts +24 -0
  13. package/dist/zauru/consolidated-history.utils.js +52 -0
  14. package/dist/zauru/costos-items.utils.d.ts +87 -0
  15. package/dist/zauru/costos-items.utils.js +601 -0
  16. package/dist/zauru/deliveries.utils.d.ts +17 -0
  17. package/dist/zauru/deliveries.utils.js +46 -0
  18. package/dist/zauru/discharges-histsory.utils.d.ts +24 -0
  19. package/dist/zauru/discharges-histsory.utils.js +46 -0
  20. package/dist/zauru/employees.utils.d.ts +16 -0
  21. package/dist/zauru/employees.utils.js +39 -0
  22. package/dist/zauru/form.utils.d.ts +34 -0
  23. package/dist/zauru/form.utils.js +152 -0
  24. package/dist/zauru/invoices.utils.d.ts +22 -0
  25. package/dist/zauru/invoices.utils.js +79 -0
  26. package/dist/zauru/items.utils.d.ts +52 -0
  27. package/dist/zauru/items.utils.js +152 -0
  28. package/dist/zauru/lotes.utils.d.ts +31 -0
  29. package/dist/zauru/lotes.utils.js +307 -0
  30. package/dist/zauru/motivos-rechazo.utils.d.ts +10 -0
  31. package/dist/zauru/motivos-rechazo.utils.js +18 -0
  32. package/dist/zauru/payees.utils.d.ts +42 -0
  33. package/dist/zauru/payees.utils.js +128 -0
  34. package/dist/zauru/profiles.utils.d.ts +15 -0
  35. package/dist/zauru/profiles.utils.js +37 -0
  36. package/dist/zauru/providers.utils.d.ts +13 -0
  37. package/dist/zauru/providers.utils.js +36 -0
  38. package/dist/zauru/purchase-orders.utils.d.ts +114 -0
  39. package/dist/zauru/purchase-orders.utils.js +376 -0
  40. package/dist/zauru/shipments.utils.d.ts +21 -0
  41. package/dist/zauru/shipments.utils.js +90 -0
  42. package/dist/zauru/specialItem.utils.d.ts +34 -0
  43. package/dist/zauru/specialItem.utils.js +62 -0
  44. package/dist/zauru/templates.utils.d.ts +49 -0
  45. package/dist/zauru/templates.utils.js +93 -0
  46. package/dist/zauru/tiposMuestra.utils.d.ts +34 -0
  47. package/dist/zauru/tiposMuestra.utils.js +62 -0
  48. package/dist/zauru/webapp-tables.utils.d.ts +16 -0
  49. package/dist/zauru/webapp-tables.utils.js +51 -0
  50. package/package.json +6 -6
  51. package/src/index.ts +23 -0
  52. package/src/zauru/bitacora-edicion-masiva.utils.ts +99 -0
  53. package/src/zauru/bundles.utils.ts +251 -0
  54. package/src/zauru/cases.utils.ts +31 -0
  55. package/src/zauru/consolidated-history.utils.ts +102 -0
  56. package/src/zauru/costos-items.utils.ts +865 -0
  57. package/src/zauru/deliveries.utils.ts +77 -0
  58. package/src/zauru/discharges-histsory.utils.ts +105 -0
  59. package/src/zauru/employees.utils.ts +59 -0
  60. package/src/zauru/form.utils.ts +243 -0
  61. package/src/zauru/invoices.utils.ts +114 -0
  62. package/src/zauru/items.utils.ts +269 -0
  63. package/src/zauru/lotes.utils.ts +411 -0
  64. package/src/zauru/motivos-rechazo.utils.ts +47 -0
  65. package/src/zauru/payees.utils.ts +213 -0
  66. package/src/zauru/profiles.utils.ts +44 -0
  67. package/src/zauru/providers.utils.ts +67 -0
  68. package/src/zauru/purchase-orders.utils.ts +594 -0
  69. package/src/zauru/shipments.utils.ts +139 -0
  70. package/src/zauru/specialItem.utils.ts +126 -0
  71. package/src/zauru/templates.utils.ts +199 -0
  72. package/src/zauru/tiposMuestra.utils.ts +136 -0
  73. package/src/zauru/webapp-tables.utils.ts +94 -0
  74. /package/src/{automatic-number.utils.ts → zauru/automatic-number.utils.ts} +0 -0
@@ -0,0 +1,269 @@
1
+ import type { Session } from "@remix-run/node";
2
+ import {
3
+ extractValueBetweenTags,
4
+ handlePossibleAxiosErrors,
5
+ } from "@zauru-sdk/common";
6
+ import {
7
+ createItem,
8
+ createItemCategory,
9
+ getItemCategoriesBySuperCategoryId,
10
+ getItemsByCategoryId,
11
+ getItemsBySuperCategoryId,
12
+ getVariablesByName,
13
+ } from "@zauru-sdk/services";
14
+ import httpZauru from "@zauru-sdk/services/dist/zauru/httpZauru.server.js";
15
+ import {
16
+ AxiosUtilsResponse,
17
+ ItemGraphQL,
18
+ SearchItemParams,
19
+ ItemDataTable,
20
+ ResponseItemList,
21
+ HTMLItemListSchema,
22
+ ItemCategoryGraphQL,
23
+ } from "@zauru-sdk/types";
24
+
25
+ /**
26
+ *
27
+ * @param headers
28
+ * @param session
29
+ * @returns
30
+ */
31
+ export const getItemsByReceptionCategory = async (
32
+ headers: any,
33
+ session: Session
34
+ ): Promise<AxiosUtilsResponse<ItemGraphQL[]>> => {
35
+ return handlePossibleAxiosErrors(async () => {
36
+ const { recepciones_item_category_id } = await getVariablesByName(
37
+ headers,
38
+ session,
39
+ ["recepciones_item_category_id"]
40
+ );
41
+
42
+ const response = await getItemsByCategoryId(
43
+ session,
44
+ recepciones_item_category_id
45
+ );
46
+
47
+ if (response.error) {
48
+ throw new Error(
49
+ `Ocurrió un error al consultar los items por categoría de recepción: ${response.userMsg}`
50
+ );
51
+ }
52
+
53
+ return response?.data ?? [];
54
+ });
55
+ };
56
+
57
+ /**
58
+ *
59
+ * @param headers
60
+ * @param session
61
+ * @returns
62
+ */
63
+ export const getItemsByLabCategory = async (
64
+ headers: any,
65
+ session: Session
66
+ ): Promise<AxiosUtilsResponse<ItemGraphQL[]>> => {
67
+ return handlePossibleAxiosErrors(async () => {
68
+ const { lab_super_category_item_id, lab_agency_id } =
69
+ await getVariablesByName(headers, session, [
70
+ "lab_super_category_item_id",
71
+ "lab_agency_id",
72
+ ]);
73
+
74
+ const response = await getItemsBySuperCategoryId(
75
+ session,
76
+ lab_super_category_item_id,
77
+ lab_agency_id
78
+ );
79
+
80
+ if (response.error) {
81
+ throw new Error(
82
+ `Ocurrió un error al consultar los items por categoría de laboratorio: ${response.userMsg}`
83
+ );
84
+ }
85
+
86
+ return response?.data ?? [];
87
+ });
88
+ };
89
+
90
+ /**
91
+ *
92
+ * @param headers
93
+ * @param session
94
+ * @returns
95
+ */
96
+ export const getItemServicesByLabCategory = async (
97
+ headers: any,
98
+ session: Session
99
+ ): Promise<AxiosUtilsResponse<ItemGraphQL[]>> => {
100
+ return handlePossibleAxiosErrors(async () => {
101
+ const { lab_services_item_category_id } = await getVariablesByName(
102
+ headers,
103
+ session,
104
+ ["lab_services_item_category_id"]
105
+ );
106
+
107
+ const response = await getItemsByCategoryId(
108
+ session,
109
+ lab_services_item_category_id
110
+ );
111
+
112
+ if (response.error) {
113
+ throw new Error(
114
+ `Ocurrió un error al consultar los items-servicios por categoría de laboratorio: ${response.userMsg}`
115
+ );
116
+ }
117
+
118
+ return response?.data ?? [];
119
+ });
120
+ };
121
+
122
+ /**
123
+ *
124
+ * @param headers
125
+ * @returns
126
+ */
127
+ export const getItemsDataTable = async (
128
+ headers: any,
129
+ search: SearchItemParams
130
+ ): Promise<AxiosUtilsResponse<ItemDataTable[]>> => {
131
+ return handlePossibleAxiosErrors(async () => {
132
+ const response = await httpZauru.post<ResponseItemList>(
133
+ `/settings/items/datatables.json`,
134
+ search,
135
+ { headers }
136
+ );
137
+
138
+ const items: ItemDataTable[] =
139
+ response.data?.data?.map((x) => formatHTMLItemList(x)) ?? [];
140
+
141
+ return items;
142
+ });
143
+ };
144
+
145
+ //============================ FORMATEADO DE ITEMS
146
+ function extractIdFromURL(input: string): number {
147
+ const regex = /\/items\/(\d+)/;
148
+ const match = input.match(regex);
149
+ return match ? parseInt(match[1], 10) : -1;
150
+ }
151
+
152
+ function formatHTMLItemList(item: HTMLItemListSchema): ItemDataTable {
153
+ return {
154
+ zid: parseInt(extractValueBetweenTags(item.zid, "a"), 10),
155
+ itemId: extractIdFromURL(item.cod),
156
+ name: extractValueBetweenTags(item.name, "a"),
157
+ stck: extractValueBetweenTags(item.stck, "i") || null,
158
+ act: extractValueBetweenTags(item.act, "i") || null,
159
+ sell: extractValueBetweenTags(item.sell, "i") || null,
160
+ purch: extractValueBetweenTags(item.purch, "i") || null,
161
+ vat: extractValueBetweenTags(item.vat, "i") || null,
162
+ cat: item.cat,
163
+ warr: item.warr,
164
+ cat_note: item.cat_note,
165
+ DT_RowId: parseInt(item.DT_RowId.replace("settings-item-", ""), 10),
166
+ };
167
+ }
168
+
169
+ /**
170
+ * getLabItemCategories
171
+ * @param session
172
+ * @param headers
173
+ * @returns
174
+ */
175
+ export async function getLabItemCategories(
176
+ headers: any,
177
+ session: Session
178
+ ): Promise<AxiosUtilsResponse<ItemCategoryGraphQL[]>> {
179
+ return handlePossibleAxiosErrors(async () => {
180
+ const { lab_super_category_item_id } = await getVariablesByName(
181
+ headers,
182
+ session,
183
+ ["lab_super_category_item_id"]
184
+ );
185
+
186
+ const response = await getItemCategoriesBySuperCategoryId(
187
+ session,
188
+ lab_super_category_item_id
189
+ );
190
+
191
+ if (response.error || !response.data) {
192
+ throw new Error(response.userMsg);
193
+ }
194
+
195
+ return response.data;
196
+ });
197
+ }
198
+
199
+ /**
200
+ * createNewLaboratoryClient
201
+ * @param session
202
+ * @param headers
203
+ * @param body
204
+ * @returns
205
+ */
206
+ export async function createNewLaboratoryItemCategory(
207
+ session: Session,
208
+ headers: any,
209
+ body: Partial<ItemCategoryGraphQL>
210
+ ): Promise<AxiosUtilsResponse<boolean>> {
211
+ return handlePossibleAxiosErrors(async () => {
212
+ const { lab_super_category_item_id } = await getVariablesByName(
213
+ headers,
214
+ session,
215
+ ["lab_super_category_item_id"]
216
+ );
217
+
218
+ const sendBody = {
219
+ ...body,
220
+ item_super_category_id: Number(lab_super_category_item_id),
221
+ color: "#ff0000",
222
+ } as ItemCategoryGraphQL;
223
+
224
+ const createResponse = await createItemCategory(headers, sendBody);
225
+
226
+ if (!createResponse.data) {
227
+ throw new Error(
228
+ `Ocurrió un error al intentar crear el item category: ${createResponse.userMsg}`
229
+ );
230
+ }
231
+
232
+ return true;
233
+ });
234
+ }
235
+
236
+ /**
237
+ * createNewLaboratoryItem
238
+ * @param session
239
+ * @param headers
240
+ * @param body
241
+ * @returns
242
+ */
243
+ export async function createNewLaboratoryItem(
244
+ headers: any,
245
+ body: Partial<ItemGraphQL>
246
+ ): Promise<AxiosUtilsResponse<ItemGraphQL>> {
247
+ return handlePossibleAxiosErrors(async () => {
248
+ const sendBody = {
249
+ active: true,
250
+ sellable: true,
251
+ quotable: true,
252
+ ecommerce: false,
253
+ purchasable: true,
254
+ weight: 0,
255
+ color: "#cccccc",
256
+ ...body,
257
+ } as ItemGraphQL;
258
+
259
+ const createResponse = await createItem(headers, sendBody);
260
+
261
+ if (!createResponse.data || createResponse.error) {
262
+ throw new Error(
263
+ `Ocurrió un error al intentar crear el item: ${createResponse.userMsg}`
264
+ );
265
+ }
266
+
267
+ return createResponse.data;
268
+ });
269
+ }
@@ -0,0 +1,411 @@
1
+ import type { Session } from "@remix-run/node";
2
+ import { getBasketsSchema, reduceAdd, toFixedIfNeeded } from "@zauru-sdk/common";
3
+ import { createNewReception, enablePurchase, getDeliveryByBooking, getLote, getLotesFiltered, getPurchase, getPurchaseOrder, getVariablesByName, insertBookings, saveMotivosDeRechazoByPurchase, updateLote, updatePurchaseOrder } from "@zauru-sdk/services";
4
+ import { BasketSchema, InsertBookingBody, NewReceptionBody, UpdatePurchaseOrderBody } from "@zauru-sdk/types";
5
+ import { getPurchaseOrderDataTables } from "./purchase-orders.utils.js";
6
+
7
+ /**
8
+ * Obtiene el listado de ordenes de compra, formateado especialmente para armar la tabla de edición de porcentajes de rechazo
9
+ * @param headers
10
+ * @param session
11
+ * @returns
12
+ */
13
+ export const getLotesFormated = async (headers: any, session: Session) => {
14
+ //PASO 1: Obtengo las variables, para buscar mi tag_id y mi basket_id
15
+ const {
16
+ recepciones_basket_item_id: basket_id,
17
+ production_agency_id /**{5693: 5696} */,
18
+ } = await getVariablesByName(headers, session, [
19
+ "recepciones_basket_item_id",
20
+ "production_agency_id",
21
+ ]);
22
+ const hashAgencyId = JSON.parse(production_agency_id ?? "{}");
23
+ const agency_id = hashAgencyId[session.get("agency_id")];
24
+
25
+ //PASO 2: Busco mis lotes
26
+ if (agency_id) {
27
+ return await getLotesFiltered(headers, agency_id, false, Number(basket_id));
28
+ }
29
+
30
+ return [];
31
+ };
32
+
33
+ /**
34
+ * procesarLote
35
+ * @param headers
36
+ * @param session
37
+ * @param data
38
+ * @param byPercent
39
+ */
40
+ export const procesarLote = async (
41
+ headers: any,
42
+ session: Session,
43
+ data: any,
44
+ poId: number | string
45
+ ) => {
46
+ //=====================================================================================
47
+ //=====================================================================================
48
+ //PASO 1: OBTENER TODAS LAS VARIABLES QUE VAMOS A UTILIZAR EN EL FLUJO
49
+ const {
50
+ production_agency,
51
+ operative_rejection_agency_id,
52
+ recepciones_basket_item_id: basket_id,
53
+ } = await getVariablesByName(headers, session, [
54
+ "production_agency",
55
+ "operative_rejection_agency_id",
56
+ "recepciones_basket_item_id",
57
+ ]);
58
+ const session_agency_id = session.get("agency_id");
59
+ const hashObject = JSON.parse(operative_rejection_agency_id);
60
+ const op_rejection_agency_id = hashObject[session_agency_id];
61
+
62
+ //PARSEO DE LA INFORMACIÓN QUE VIENE DEL SUBMIT
63
+ const byPercent = data.byPercent === "true";
64
+ const porcentajeRechazo = !byPercent
65
+ ? toFixedIfNeeded(
66
+ (Number(data.lbRechazo ?? "0") /
67
+ (Number(data?.lbRechazo ?? "0") + Number(data.lbBueno))) *
68
+ 100
69
+ )
70
+ : data.porcentajeRechazo;
71
+ const basket_keys = Object.keys(data).filter((x) => x.includes("basket-"));
72
+ const baskets_regresadas = basket_keys.map((basket_key: string) => {
73
+ //ejemplo de una key: basket-CONVENCIONAL-58281
74
+ const splited = basket_key.split("-");
75
+ return {
76
+ id: splited[2] || 0,
77
+ color: splited[1] || "",
78
+ total: Number(data[basket_key]) || 0,
79
+ } as BasketSchema;
80
+ });
81
+
82
+ //1.2 OBTENER LA INFORMACIÓN DEL LOTE A PROCESAR (LA TOMO DE LA QUE YA TENGO AL CARGAR LA INFO)
83
+ const purchaseOrderResponse = await getPurchaseOrder(session, poId, {
84
+ withLotStocksToMyAgency: true,
85
+ });
86
+
87
+ if (purchaseOrderResponse.error || !purchaseOrderResponse?.data) {
88
+ throw new Error(
89
+ `Error al intentar encontrar la órden de compra: ${purchaseOrderResponse.userMsg}`
90
+ );
91
+ }
92
+
93
+ const purchaseOrder = purchaseOrderResponse.data;
94
+ const lbsEsperadas = purchaseOrder.lots[0].lot_stocks[0].available;
95
+
96
+ const lbsMalas = lbsEsperadas * (Number(porcentajeRechazo) / 100);
97
+ const lbsBuenas = lbsEsperadas - lbsMalas;
98
+
99
+ const baskets_memo = getBasketsSchema(purchaseOrder.memo);
100
+ const baskets_memo_quantity = baskets_memo
101
+ .map((basket) => basket.total)
102
+ .reduce(reduceAdd, 0);
103
+
104
+ //SI SE INGRESA POR LIBRAS, ES QUE SE ESTÁ INGRESANDO CANASTAS A DEVOLVER ETC Y HAY QUE HACER LOS ENVÍOS CORRESPONDIENTES
105
+ if (!byPercent) {
106
+ console.log("=============> PROCESANDO DATA POR PESO...");
107
+ //CUANDO NO ES POR PORCENTAJE DIRECTO HAY QUE HACER TODO EL FLUJO DE CREAR LOS ENVÍOS ETC...
108
+ //1.3: SE CREA EL ENVÍO DE VEGETALES Y CANASTAS DEVUELTOS POR CONTROL DE CALIDAD, (LOS QUE ESTÁN BUENOS)
109
+ //Las canastas vienen en data en campos como estos "basket-CONVENCIONAL-58281": "2",
110
+ const bodyGoodToProduction: InsertBookingBody = {
111
+ booker_id: Number(session.get("employee_id")),
112
+ needs_transport: false,
113
+ payee_id: purchaseOrder.payee_id,
114
+ memo: `${purchaseOrder.lots[0].id};${purchaseOrder.id_number};${
115
+ purchaseOrder.purchase_order_details[0]?.item?.name
116
+ };${purchaseOrder.purchase_order_details
117
+ .map((purchase) => Number(purchase.booked_quantity))
118
+ .reduce(reduceAdd, 0)};${baskets_memo_quantity};${porcentajeRechazo};${
119
+ purchaseOrder.delivery_date
120
+ }`,
121
+ planned_delivery: `${data.date}`,
122
+ agency_from_id: Number(session_agency_id), //agencia donde está loggeado mi usuario
123
+ agency_to_id: purchaseOrder.agency_id, //de donde viene la orden de compra
124
+ reference: "Vegetales buenos devueltos desde control de calidad.",
125
+ movements: [
126
+ {
127
+ item_id: purchaseOrder.purchase_order_details[0].item_id,
128
+ lot_id: purchaseOrder.lots[0].id,
129
+ reference: "Vegetales devueltos de CC",
130
+ booked_quantity: lbsBuenas,
131
+ },
132
+ ],
133
+ };
134
+ /**
135
+ * Para las canastas
136
+ * el item_id = 490533 = recepciones_basket_item_id
137
+ * lot_id: código de la canasta,
138
+ * booked_quantity = cantidad de canastas que ingresa el usuario que va a devolver
139
+ */
140
+ baskets_regresadas.forEach((basket: BasketSchema) => {
141
+ bodyGoodToProduction.movements.push({
142
+ item_id: Number(basket_id),
143
+ lot_id: basket.id,
144
+ reference: `Canasta ${basket.color}-${basket.id} devuelta a CC`,
145
+ booked_quantity: basket.total,
146
+ });
147
+ });
148
+
149
+ console.log("-------- Insertando booking con canastas buenas devueltas");
150
+ const goodVegetablesInserted = await insertBookings(
151
+ headers,
152
+ bodyGoodToProduction,
153
+ `${purchaseOrder.id}`
154
+ );
155
+
156
+ if (!goodVegetablesInserted.error && goodVegetablesInserted.data) {
157
+ //1.4 Recibir la reserva para que las cantidades se muevan correctamente a la bodega de destino
158
+ console.log("recibiendo la reserva: ", goodVegetablesInserted.data?.id);
159
+ await getDeliveryByBooking(headers, goodVegetablesInserted.data?.id);
160
+ }
161
+
162
+ if (lbsMalas && lbsMalas > 0) {
163
+ //=====================================================================================
164
+ //=====================================================================================
165
+ //PASO 2: Envío con vegetales rechazados a bodega de PRODUCCIÓN desde la agencia del usuario loggeado
166
+ const bodyOchToProduction: InsertBookingBody = {
167
+ booker_id: Number(session.get("employee_id")),
168
+ needs_transport: false,
169
+ memo: "",
170
+ planned_delivery: `${data.date}`,
171
+ agency_from_id: Number(session_agency_id), //agencia donde está loggeado mi usuario
172
+ agency_to_id: Number(production_agency), //de donde viene la orden de compra
173
+ reference: "Envío de vegetales rechazados a la bodega de producción.",
174
+ movements: [
175
+ {
176
+ item_id: purchaseOrder.purchase_order_details[0].item_id,
177
+ lot_id: purchaseOrder.lots[0].id,
178
+ reference: "Vegetales rechazados de CC",
179
+ booked_quantity: lbsMalas,
180
+ },
181
+ ],
182
+ };
183
+
184
+ console.log(
185
+ "--------- enviando a insertar booking de rechazo a la bodega de producción"
186
+ );
187
+ const ochToProductionVegetablesInserted = await insertBookings(
188
+ headers,
189
+ bodyOchToProduction,
190
+ `${purchaseOrder.id}`
191
+ );
192
+
193
+ if (
194
+ !ochToProductionVegetablesInserted.error &&
195
+ ochToProductionVegetablesInserted.data
196
+ ) {
197
+ //2.1 Recibir la reserva para que las cantidades se muevan correctamente a la bodega de destino
198
+ console.log("Recibiendo booking de rechazo...");
199
+ await getDeliveryByBooking(
200
+ headers,
201
+ ochToProductionVegetablesInserted.data.id
202
+ );
203
+ }
204
+ //=====================================================================================
205
+ //=====================================================================================
206
+ //PASO 3: Envío con vegetales rechazados a bodega de RECHAZO desde la bodega de PRODUCCIÓN
207
+ //Sólo cambia el agency_from_id y el agency_to_id, de ahí lo demás lo mismo que PASO 2
208
+ bodyOchToProduction.agency_from_id = Number(production_agency);
209
+ bodyOchToProduction.agency_to_id = Number(op_rejection_agency_id);
210
+ bodyOchToProduction.reference =
211
+ "Envío de vegetales rechazados a la bodega de rechazo.";
212
+
213
+ console.log(
214
+ "--------- enviando a insertar booking de rechazo a la bodega de rechazo"
215
+ );
216
+ const ochToOchVegetablesInserted = await insertBookings(
217
+ headers,
218
+ bodyOchToProduction
219
+ );
220
+
221
+ if (
222
+ !ochToOchVegetablesInserted.error &&
223
+ ochToOchVegetablesInserted.data
224
+ ) {
225
+ //3.1 Recibir la reserva para que las cantidades se muevan correctamente a la bodega de destino
226
+ await getDeliveryByBooking(
227
+ headers,
228
+ ochToOchVegetablesInserted.data?.id
229
+ );
230
+ }
231
+ }
232
+
233
+ //=====================================================================================
234
+ //=====================================================================================
235
+ //PASO 5: Modificación de canastas en el lote de verdura
236
+ //la misma description del detalle del lote pero modificando la cantidad de canastas que quedaron.
237
+ //ejemplo: original: 27-53311-VERDE,1-53313-ROJA,1-53317-CELESTE,3-53312-AZUL,3-53314-AMARILLA
238
+ //ahora: 27-53311-VERDE,1-53313-ROJA,1-53317-CELESTE,2-53312-AZUL,3-53314-AMARILLA // ahora sólo 2 azules porque no devolví una
239
+ const newDescriptions: Array<string> = [];
240
+ baskets_memo.forEach((basket: BasketSchema) => {
241
+ //Si existe una basket a regresar con el mismo id, pregunto cuantas va a regresar, para restarlas del total.
242
+ const basket_regresada = baskets_regresadas.find(
243
+ (x) => x.id === basket.id
244
+ );
245
+ const resta = basket_regresada?.total ?? 0;
246
+ newDescriptions.push(
247
+ `${basket.total - resta}-${basket.id}-${basket.color}`
248
+ );
249
+ });
250
+
251
+ await updateLote(headers, purchaseOrder.lots[0].id, {
252
+ lot: {
253
+ description: newDescriptions.join(","),
254
+ },
255
+ });
256
+ } else {
257
+ console.log("PROCESANDO DATA POR PORCENTAJE...");
258
+ //CUANDO NO ES POR PORCENTAJE DIRECTO HAY QUE HACER TODO EL FLUJO DE CREAR LOS ENVÍOS ETC...
259
+ //1.3: SE CREA EL ENVÍO DE VEGETALES Y CANASTAS DEVUELTOS POR CONTROL DE CALIDAD, (LOS QUE ESTÁN BUENOS)
260
+ //Las canastas vienen en data en campos como estos "basket-CONVENCIONAL-58281": "2",
261
+ const bodyGoodToProduction: InsertBookingBody = {
262
+ booker_id: Number(session.get("employee_id")),
263
+ needs_transport: false,
264
+ payee_id: purchaseOrder.payee_id,
265
+ memo: `${purchaseOrder.lots[0].id};${purchaseOrder.lots[0].name};${
266
+ purchaseOrder.purchase_order_details[0]?.item?.name
267
+ };${purchaseOrder.purchase_order_details
268
+ .map((detail) => Number(detail.booked_quantity))
269
+ .reduce(reduceAdd, 0)};${baskets_memo_quantity};${porcentajeRechazo};${
270
+ purchaseOrder.delivery_date
271
+ }`,
272
+ planned_delivery: `${data.date}`,
273
+ agency_from_id: Number(session_agency_id), //agencia donde está loggeado mi usuario
274
+ agency_to_id: purchaseOrder.agency_id, //de donde viene la orden de compra
275
+ reference: "Regreando vegetales buenos desde control de calidad.",
276
+ movements: [
277
+ {
278
+ item_id: purchaseOrder.purchase_order_details[0].item_id,
279
+ lot_id: purchaseOrder.lots[0].id,
280
+ reference: "Vegetales devueltos de CC",
281
+ booked_quantity: lbsEsperadas, //devuelvo la misma cantidad que fue enviada
282
+ },
283
+ ],
284
+ };
285
+ /**
286
+ * Para las canastas
287
+ * el item_id = 490533 = recepciones_basket_item_id
288
+ * lot_id: código de la canasta,
289
+ * booked_quantity = cantidad de canastas que ingresa el usuario que va a devolver
290
+ */
291
+ //Todas las canastas que fueron enviadas originalmente
292
+ baskets_memo.forEach((basket: BasketSchema) => {
293
+ bodyGoodToProduction.movements.push({
294
+ item_id: Number(basket_id),
295
+ lot_id: basket.id,
296
+ reference: `Canasta ${basket.color}-${basket.id} devuelta a CC`,
297
+ booked_quantity: basket.total,
298
+ });
299
+ });
300
+ console.log("-------- Insertando booking con canastas buenas devueltas");
301
+ const goodVegetablesInserted = await insertBookings(
302
+ headers,
303
+ bodyGoodToProduction,
304
+ `${purchaseOrder.id}`
305
+ );
306
+
307
+ //1.4 Recibir la reserva para que las cantidades se muevan correctamente a la bodega de destino
308
+ if (!goodVegetablesInserted.error && goodVegetablesInserted.data) {
309
+ console.log("A RECIBIR BOOKING - POR PORCENTAJE");
310
+ await getDeliveryByBooking(headers, goodVegetablesInserted.data.id);
311
+ }
312
+ }
313
+
314
+ //=====================================================================================
315
+ //=====================================================================================
316
+ //PASO 4: Modificación de porcentaje de rechazo en la orden de compra
317
+ //4.1 El primer paso es devolver la recepción recibida en la orden de compra.
318
+ //Primero se debe obtener el id de dicha recepción
319
+ const reception = purchaseOrder.receptions[0];
320
+ const reception_details = reception?.reception_details[0];
321
+
322
+ //4.2 Habilito la orden de compra
323
+ await enablePurchase(headers, purchaseOrder.id, reception?.id);
324
+
325
+ //4.3 Editar porcentajes de rechazo
326
+ const updateBodyPurchase = {
327
+ purchase_order: { discount: porcentajeRechazo },
328
+ } as UpdatePurchaseOrderBody;
329
+ await updatePurchaseOrder(headers, updateBodyPurchase, purchaseOrder.id);
330
+
331
+ //4.4 Crear una nueva recepcion
332
+ const bodyReception = {
333
+ reception: {
334
+ agency_id: reception.agency_id,
335
+ entity_id: reception.entity_id,
336
+ needs_transit: false,
337
+ purchase_order_id: purchaseOrder.id,
338
+ received_at: new Date(Date.now() + 12096e5).toISOString().split("T")[0],
339
+ invoice_number: `${reception.invoice_number ?? ""}`,
340
+ reception_details_attributes: {
341
+ "0": {
342
+ item_id: `${reception_details?.item_id}`,
343
+ lot_delivered_quantity: [reception_details?.lot_delivered_quantity],
344
+ lot_description: [reception_details?.lot_description],
345
+ lot_expire: [reception_details?.lot_expire],
346
+ lot_name: [reception_details?.lot_name],
347
+ purchase_order_detail_id: `${reception_details?.purchase_order_detail_id}`,
348
+ },
349
+ },
350
+ },
351
+ } as NewReceptionBody;
352
+ await createNewReception(headers, bodyReception, purchaseOrder.id);
353
+
354
+ //=====================================================================================
355
+ //=====================================================================================
356
+ //PASO 6: Guardar razones de rechazo en webapp table
357
+ await saveMotivosDeRechazoByPurchase(
358
+ headers,
359
+ session,
360
+ {
361
+ Razon_primaria: `${data.razonPrincipal ?? ""}`,
362
+ Razon_secundaria: `${data.razonSecundaria ?? ""}`,
363
+ Razon_terciaria: `${data.razonTerciaria ?? ""}`,
364
+ Canastas: `${data.ochBaskets ?? ""}`,
365
+ },
366
+ {
367
+ temp_purchase_order_id: `${purchaseOrder.id}`,
368
+ }
369
+ );
370
+ };
371
+
372
+ /**
373
+ * Obtiene toda la información de lote, con las canastas y razones de rechazo
374
+ * @param headers
375
+ * @param session
376
+ * @returns
377
+ */
378
+ export const getLoteDescription = async (
379
+ headers: any,
380
+ session: Session,
381
+ lote_id: number
382
+ ) => {
383
+ //PASO 1: Obtengo las variables, para buscar mi basket_id
384
+ const { production_agency_id /**{5693: 5696} */ } = await getVariablesByName(
385
+ headers,
386
+ session,
387
+ ["production_agency_id"]
388
+ );
389
+ const hashAgencyId = JSON.parse(production_agency_id ?? "{}");
390
+ const agency_id = hashAgencyId[session.get("agency_id")];
391
+
392
+ //PASO 2: Busco mi lote
393
+ const lote = await getLote(headers, lote_id, agency_id);
394
+
395
+ //PASO 3: Obtener listado de canastas enviadas a bodega control de calidad
396
+ //El primer paso es ubicar la orden de compra original, la cual permitirá ubicar el envío que se
397
+ //realizó a la bodega de control de calidad
398
+ const purchase_order = await getPurchaseOrderDataTables(
399
+ headers,
400
+ lote.name.replace("-RETENIDO", "") // por si trae la palabra RETENIDO,
401
+ );
402
+
403
+ //PASO 4: Obtener los envíos asociados a la orden de compra
404
+ const purchaseResponse = await getPurchase(headers, purchase_order.no_orden);
405
+
406
+ return {
407
+ lote,
408
+ purchase_order,
409
+ purchase: purchaseResponse.data,
410
+ };
411
+ };