From 83d45da5c3d6e57c619064d3fafa9893c8a90c55 Mon Sep 17 00:00:00 2001 From: liuxy Date: Wed, 13 Mar 2024 09:08:53 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9A=E6=96=B0=E5=A2=9E=E9=9C=80?= =?UTF-8?q?=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../st/rest/StructattrController.java | 14 + .../st/service/StructattrService.java | 19 ++ .../st/service/impl/StorattrServiceImpl.java | 4 +- .../service/impl/StructattrServiceImpl.java | 156 ++++++++++ .../st/service/impl/StructivtServiceImpl.java | 13 +- .../wms/basedata/st/wql/QST_STRUCTIVT001.wql | 47 ++- .../java/org/nl/wms/basedata/st/wql/stivt.xls | Bin 325120 -> 326144 bytes .../impl/SubpackagerelationServiceImpl.java | 2 + .../impl/RawAssistIStorServiceImpl.java | 69 ++++- .../service/impl/StorPublicServiceImpl.java | 5 + .../st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql | 43 ++- .../instor/rest/ProductScrapController.java | 9 + .../instor/service/ProductScrapService.java | 11 + .../service/impl/HandMoveStorServiceImpl.java | 53 +++- .../service/impl/ProductScrapServiceImpl.java | 71 +++++ .../st/instor/wql/QST_IVT_HANDMOVESTOR.wql | 33 ++- .../service/impl/CheckOutBillServiceImpl.java | 279 ++++++++++++++++-- .../st/outbill/wql/QST_IVT_CHECKOUTBILL.wql | 78 ++++- .../org/nl/wms/st/outbill/wql/ST_OUTIVT01.wql | 11 +- .../impl/InAndOutRetrunServiceImpl.java | 78 ++++- .../st/returns/wql/QST_IVT_INANDOUTRETRUN.wql | 37 ++- .../service/impl/OutBillQueryServiceImpl.java | 1 + .../src/views/wms/basedata/st/ivt/index.vue | 26 +- .../src/views/wms/basedata/st/stor/index.vue | 20 +- .../basedata/st/struct/OneCreateDialog.vue | 161 ++++++++++ .../views/wms/basedata/st/struct/index.vue | 22 +- .../wms/basedata/st/struct/structattr.js | 18 +- .../wms/st/inStor/productscrap/AddDialog.vue | 23 +- .../st/inStor/productscrap/UploadDialog.vue | 120 ++++++++ .../wms/st/inStor/productscrap/index.vue | 1 + .../st/inStor/productscrap/productscrap.js | 9 +- .../src/views/wms/st/inbill/index.vue | 19 ++ .../src/views/wms/st/outbill/DivDialog.vue | 7 +- .../src/views/wms/st/outbill/ViewDialog.vue | 9 +- .../src/views/wms/st/outbill/index.vue | 9 + 35 files changed, 1386 insertions(+), 91 deletions(-) create mode 100644 lms/nladmin-ui/src/views/wms/basedata/st/struct/OneCreateDialog.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/inStor/productscrap/UploadDialog.vue diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/rest/StructattrController.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/rest/StructattrController.java index 30e651073..8419eb78f 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/rest/StructattrController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/rest/StructattrController.java @@ -94,4 +94,18 @@ public class StructattrController { public ResponseEntity unLockPoint(@RequestBody JSONObject whereJson) { return new ResponseEntity<>(structattrService.unLockPoint(whereJson), HttpStatus.OK); } + + @PostMapping("/oneCreate") + @Log("一键生成货位") + public ResponseEntity oneCreate(@RequestBody JSONObject whereJson) { + structattrService.oneCreate(whereJson); + return new ResponseEntity<>( HttpStatus.OK); + } + + @PostMapping("/blurQuery") + @Log("校验前缀是否可用") + public ResponseEntity blurQuery(@RequestBody JSONObject whereJson) { + structattrService.blurQuery(whereJson); + return new ResponseEntity<>( HttpStatus.OK); + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/StructattrService.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/StructattrService.java index aa54af38d..6e8d4296c 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/StructattrService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/StructattrService.java @@ -98,4 +98,23 @@ public interface StructattrService { * @return */ JSONObject unLockPoint(JSONObject whereJson); + + /** + * 一键生成货位 + * @param whereJson { + * stor_id: 仓库id + * sect_id: 库区id + * prefix: 仓位前缀 + * num: 生成数量 + * } + */ + void oneCreate(JSONObject whereJson); + + /** + * 校验前缀是否可用 + * @param whereJson { + * prefix: 前缀 + * } + */ + void blurQuery(JSONObject whereJson); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StorattrServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StorattrServiceImpl.java index 8206d68ac..5a22b65b4 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StorattrServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StorattrServiceImpl.java @@ -98,7 +98,9 @@ public class StorattrServiceImpl implements StorattrService { dto.setCreate_time(now); //TODO - dto.setSyscompanyid(18L); + dto.setSyscompanyid(9L); + dto.setSysdeptid(9L); + dto.setSysownerid(9L); WQLObject wo = WQLObject.getWQLObject("st_ivt_bsrealstorattr"); JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java index 1f0446d24..e7bd880af 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructattrServiceImpl.java @@ -513,4 +513,160 @@ public class StructattrServiceImpl implements StructattrService { return null; } + @Override + @Transactional(rollbackFor = Exception.class) + public void oneCreate(JSONObject whereJson) { + // 仓位表 + WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr"); + // 库区表 + WQLObject sectTab = WQLObject.getWQLObject("st_ivt_sectattr"); + // 点位表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + // 仓库表 + WQLObject storTab = WQLObject.getWQLObject("st_ivt_bsrealstorattr"); + + // 判断库区是否是虚拟区 + JSONObject jsonSect = sectTab.query("sect_id = '" + whereJson.getString("sect_id") + "'").uniqueResult(0); + + if (!jsonSect.getString("sect_type_attr").equals("09")) { + throw new BadRequestException("所选库区必须是虚拟区!"); + } + + /* + * 判断此库区是否已经生成仓位 + */ + JSONObject jsonAttr = attrTab.query("sect_id = '" + whereJson.getString("sect_id") + "' order by struct_code DESC").uniqueResult(0); + + // 生成数量 + int createNum = whereJson.getIntValue("num"); + // 开始生成数 + int createNum_start = 1; + // 前缀 + String prefix = whereJson.getString("prefix"); + + if (ObjectUtil.isNotEmpty(jsonAttr)) { + String struct_code = jsonAttr.getString("struct_code"); + + // 第一个-的位置 + int firstIndex = struct_code.indexOf("-"); + // 第二个-的位置 + int secondIndex = struct_code.substring(firstIndex + 1).indexOf("-") + firstIndex; + // 最大的仓位数 + String result = struct_code.substring(firstIndex + 1, secondIndex +1); + + createNum += Integer.parseInt(result); + + createNum_start += Integer.parseInt(result); + + prefix = struct_code.substring(0, firstIndex); + } + + /* + * 生成货位 + */ + String now = DateUtil.now(); + for (int i = createNum_start; i <= createNum; i++) { + + JSONObject json = new JSONObject(); + json.put("struct_id", IdUtil.getSnowflake(1,1).nextId()); + + if (i < 10) { + json.put("struct_code", prefix + "-"+"000"+i+"-01"); + json.put("struct_name", prefix + "排-"+"000"+i+"列-01层"); + + }else if (i >= 10 && i < 100) { + json.put("struct_code", prefix + "-"+"00"+i+"-01"); + json.put("struct_name", prefix + "排-"+"00"+i+"列-01层"); + }else if (i >= 100 && i < 1000) { + json.put("struct_code", prefix + "-"+"0"+i+"-01"); + json.put("struct_name", prefix + "排-"+"0"+i+"列-01层"); + } else { + json.put("struct_code", prefix + "-"+i+"-01"); + json.put("struct_name", prefix + "排-"+i+"列-01层"); + } + JSONObject jsonObject = storTab.query("stor_id = '"+whereJson.getString("stor_id")+"'").uniqueResult(0); + JSONObject jsonObjec2 = sectTab.query("stor_id = '"+whereJson.getString("stor_id")+"' and sect_id = '"+whereJson.getString("sect_id")+"'").uniqueResult(0); + + // 新增仓位 + json.put("simple_name", json.getString("struct_name")); + json.put("sect_id", jsonObjec2.getString("sect_id")); + json.put("sect_code", jsonObjec2.getString("sect_code")); + json.put("sect_name", jsonObjec2.getString("sect_name")); + json.put("stor_id", jsonObject.getString("stor_id")); + json.put("stor_code", jsonObject.getString("stor_code")); + json.put("stor_name", jsonObject.getString("stor_name")); + json.put("lock_type", "1"); + json.put("row_num", 1); + json.put("col_num", i); + json.put("layer_num", 1); + json.put("block_num", 1); + json.put("in_order_seq", i); + json.put("out_order_seq", i); + json.put("in_empty_seq", i); + json.put("out_empty_seq", i); + json.put("create_id", "1"); + json.put("create_name", "管理员"); + json.put("create_time", now); + json.put("material_height_type", 1); + attrTab.insert(json); + + // 新增点位 + JSONObject jsonPoint = new JSONObject(); + jsonPoint.put("point_id",IdUtil.getSnowflake(1,1).nextId()); + jsonPoint.put("point_code", json.getString("struct_code")); + jsonPoint.put("point_name", json.getString("struct_name")); + jsonPoint.put("region_id", json.getString("sect_id")); + jsonPoint.put("region_code", json.getString("sect_code")); + jsonPoint.put("region_name", json.getString("sect_name")); + jsonPoint.put("point_type", "2"); + jsonPoint.put("point_status", "1"); + jsonPoint.put("lock_type", "1"); + jsonPoint.put("vehicle_max_qty", 0); + jsonPoint.put("vehicle_qty", 0); + jsonPoint.put("block_num", 1); + jsonPoint.put("row_num", 1); + jsonPoint.put("col_num", 1); + jsonPoint.put("layer_num", 1); + jsonPoint.put("in_order_seq", 0); + jsonPoint.put("out_order_seq", 0); + jsonPoint.put("in_empty_seq", 0); + jsonPoint.put("out_empty_seq", 0); + jsonPoint.put("is_have_workder", "0"); + jsonPoint.put("is_used", "1"); + jsonPoint.put("source_id", json.get("struct_id")); + jsonPoint.put("is_delete", "0"); + jsonPoint.put("create_id", "1"); + jsonPoint.put("create_name", "管理员"); + jsonPoint.put("create_time", now); + pointTab.insert(jsonPoint); + } + + } + + @Override + public void blurQuery(JSONObject whereJson) { + // 仓位表 + WQLObject attrTab = WQLObject.getWQLObject("st_ivt_structattr"); + + /* + * 判断前缀是否存在 + */ + List attrList = attrTab.query("1 = 1").getResultJSONArray(0).toJavaList(JSONObject.class); + + // 截取第一个 - 之前的数据集合 + List subStringList = attrList.stream() + .filter(row -> row.getString("struct_code").contains("-")) + .map(row -> row.getString("struct_code").substring(0, row.getString("struct_code").indexOf("-"))) + .distinct() + .collect(Collectors.toList()); + + // 判断是否有相同的前缀 + boolean is_like = subStringList.stream() + .anyMatch(row -> row.equals(whereJson.getString("prefix"))); + + if (is_like) { + throw new BadRequestException("此前缀已存在,请更换!"); + } + } + } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructivtServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructivtServiceImpl.java index a37c84e7a..8f2d69d67 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructivtServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/service/impl/StructivtServiceImpl.java @@ -48,7 +48,6 @@ public class StructivtServiceImpl implements StructivtService { @Override public Map queryAll(Map whereJson, Pageable page, String[] product_area, String[] ivt_flag) { String material = MapUtil.getStr(whereJson, "material"); - //哈哈哈哈哈222 String struct = MapUtil.getStr(whereJson, "struct"); String stor_id = MapUtil.getStr(whereJson, "stor_id"); String sect_id = MapUtil.getStr(whereJson, "sect_id"); @@ -58,12 +57,14 @@ public class StructivtServiceImpl implements StructivtService { String sale_order_name = MapUtil.getStr(whereJson, "sale_order_name"); String ivt_status = MapUtil.getStr(whereJson, "ivt_status"); String is_virtual = MapUtil.getStr(whereJson, "is_virtual"); + String sub_type = MapUtil.getStr(whereJson, "sub_type"); JSONObject map = new JSONObject(); map.put("flag", "1"); map.put("stor_id", stor_id); map.put("sect_id", sect_id); map.put("ivt_status", ivt_status); map.put("is_virtual", is_virtual); + map.put("sub_type", sub_type); if (StrUtil.isNotEmpty(material)) { map.put("material", "%" + material + "%"); } @@ -220,11 +221,13 @@ public class StructivtServiceImpl implements StructivtService { String is_virtual = MapUtil.getStr(whereJson, "is_virtual"); String rein_flag = MapUtil.getStr(whereJson, "rein_flag"); String ivt_status = MapUtil.getStr(whereJson, "ivt_status"); + String sub_type = MapUtil.getStr(whereJson, "sub_type"); JSONObject map = new JSONObject(); map.put("flag", "2"); map.put("stor_id", stor_id); map.put("is_virtual", is_virtual); map.put("ivt_status", ivt_status); + map.put("sub_type", sub_type); if (StrUtil.isNotEmpty(material)) { map.put("material", "%" + material + "%"); } @@ -295,6 +298,14 @@ public class StructivtServiceImpl implements StructivtService { mp.put("业务员", json.getString("sales_owner")); mp.put("入库日期", json.getString("instorage_time")); mp.put("生产日期", json.getString("date_of_production")); + if ("1".equals(json.getString("sub_type"))) { + mp.put("子卷状态", "正常"); + } else if ("2".equals(json.getString("sub_type"))) { + mp.put("子卷状态", "临期"); + } else if ("3".equals(json.getString("sub_type"))) { + mp.put("子卷状态", "超期"); + } + mp.put("库龄", json.getString("stock_age")); mp.put("产品规格(幅宽)", String.format("%.0f", json.getDoubleValue("width"))); mp.put("产品厚度", json.getString("thickness")); mp.put("单位面积重量", json.getString("mass_per_unit_area")); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCTIVT001.wql b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCTIVT001.wql index 22a9c0cb7..f06c3ed29 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCTIVT001.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/QST_STRUCTIVT001.wql @@ -27,6 +27,7 @@ 输入.is_virtual TYPEAS s_string 输入.rein_flag TYPEAS f_string 输入.in_stor_id TYPEAS f_string + 输入.sub_type TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -73,7 +74,16 @@ case when plan.paper_tube_or_FRP = '1' then '纸管' when plan.paper_tube_or_FRP = '2' then 'FRP管' end AS paper_type, case when plan.paper_tube_or_FRP = '1' then plan.paper_tube_material when plan.paper_tube_or_FRP = '2' then plan.FRP_material end AS paper_code, case when plan.paper_tube_or_FRP = '1' then plan.paper_tube_description when plan.paper_tube_or_FRP = '2' then plan.FRP_description end AS paper_name, - sub.box_weight + sub.box_weight, + CASE + WHEN DATEDIFF( NOW(), sub.date_of_production ) > '60' + AND DATEDIFF( NOW(), sub.date_of_production ) <= '90' THEN '2' + WHEN DATEDIFF( NOW(), sub.date_of_production ) <= '90' THEN '1' + WHEN DATEDIFF( NOW(), sub.date_of_production ) > '90' THEN '3' + + END AS sub_type, + DATEDIFF( NOW(), ivt.instorage_time ) AS stock_age + FROM ST_IVT_StructIvt ivt LEFT JOIN st_ivt_structattr attr ON ivt.struct_id = attr.struct_id @@ -134,6 +144,19 @@ attr.stor_id = 输入.stor_id ENDOPTION + OPTION 输入.sub_type = "1" + DATEDIFF( NOW(), sub.date_of_production ) <= '90' + ENDOPTION + + OPTION 输入.sub_type = "2" + DATEDIFF( NOW(), sub.date_of_production ) > '60' + AND DATEDIFF( NOW(), sub.date_of_production ) <= '90' + ENDOPTION + + OPTION 输入.sub_type = "3" + DATEDIFF( NOW(), sub.date_of_production ) > '90' + ENDOPTION + OPTION 输入.sect_id <> "" attr.sect_id = 输入.sect_id ENDOPTION @@ -205,7 +228,14 @@ case when plan.paper_tube_or_FRP = '1' then plan.paper_tube_description when plan.paper_tube_or_FRP = '2' then plan.FRP_description end AS paper_name, sub.thickness_request, sub.box_weight, - cust.sales_owner + cust.sales_owner, + CASE + WHEN DATEDIFF( NOW(), sub.date_of_production ) > '60' + AND DATEDIFF( NOW(), sub.date_of_production ) <= '90' THEN '2' + WHEN DATEDIFF( NOW(), sub.date_of_production ) <= '90' THEN '1' + WHEN DATEDIFF( NOW(), sub.date_of_production ) > '90' THEN '3' + END AS sub_type, + DATEDIFF( NOW(), ivt.instorage_time ) AS stock_age FROM ST_IVT_StructIvt ivt LEFT JOIN st_ivt_structattr attr ON ivt.struct_id = attr.struct_id @@ -249,6 +279,19 @@ ivt.pcsn like 输入.pcsn ENDOPTION + OPTION 输入.sub_type = "1" + DATEDIFF( NOW(), sub.date_of_production ) <= '90' + ENDOPTION + + OPTION 输入.sub_type = "2" + DATEDIFF( NOW(), sub.date_of_production ) > '60' + AND DATEDIFF( NOW(), sub.date_of_production ) <= '90' + ENDOPTION + + OPTION 输入.sub_type = "3" + DATEDIFF( NOW(), sub.date_of_production ) > '90' + ENDOPTION + OPTION 输入.sap_pcsn <> "" sub.sap_pcsn like 输入.sap_pcsn ENDOPTION diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/stivt.xls b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/st/wql/stivt.xls index 422f1ef4ba15ae4871c21b789aed0e71f635fc3c..2a54c742cb043466b72cdbc2d34010b21224574c 100644 GIT binary patch delta 39267 zcma*Q2V51$_dYy3d#MU2ioGEAPFJiHL9zFSu^=cY0s{8v#crZWRHAEQHa=9Mka zoSu1m`hT~8x6LlK2<4V%rAkuGWs7^+9j;scs2m@aL}uWimr+f^~gcd@Uw zB`07*aE|}%BHC%RHP_DMY}nPDo})RPrqrV6MR7qC7e#SN6hHAI=l5N$a{BHnlC$$W z-<%V>eCb`*T!uF_+S5Ph@^`-4FC6Uhcb;1w?K$RSFZZ4XR#ema#2Zsd5i)QPtJ}2c zi35|K&-5I`+NPw5w)Di*f#cqv*@LxRnJn6Fx7S8j8p7H<$^Gf9P1llU_>K4J$9hf6 z5xvf~&*}TRNBC&g*2#l%gq*%Tne}}yHfPxR3dUC{df^=7e65-#=%50orNoPnCxnS3&QERtU;BlS#;7&g z^85K+TF%?^<#N_uEaP(7g>^i$<;cZQnv?yLTh6PCUUM&Rb?S#(f84U;ax2Z~*_9T~ z@weHG=G(L)Tf(ju);#JH?MZPPEJj?ORLQAi^XZCK}}?_UkN{^#$RE$(@D7vXV8QgwxQ@69T zY%Q9-Z2SJ2HYJ~bd~T-g^G)3*8I>eN6U;n^B_3k z^5f~vZ?ziQF4BFj_s-)z%arWw-DqUQ$@opKC;kZb`Ls#S4`)BVd!%@sYnun#n=P$B zZfEyt4I2$lynLqN+<8;(?%2Au>&wDDM?PY`eys9_-d!{`a`|tiw>G)bzhvIYhx>p2 z;BdpO`#uc1)2F-yHhNz-r){QOU_^Qu)AkY?RqOe zp77rIl)}fZhY$X1a*wDV53E~bgdLB%xiPqnZJzyH>z>tCM&Ikv@A%&FPcssqUffmj zqm5tLK03JVY|Rp5eywsjCcDuxZ3YeVb$asri*V0nvkqPOv1j37S386sZMZnEeV*3p z=b);a%QngE)ZBFz4I;7EOV9hMUgoo({-}Aj$7g?T3tbcTWgB`n+{LL#;=TAKLo$*! z%!+#UGu_+c*GG+#?EBw^)vkKE%ETeRo+{VdWn5x~d23p~9}>2;$M})E|Ge;c-q>#@ zzxr%p?Qz{c3px1F`fU5E{Kh?g7@YF*hi-T4jK25NtiF?HL_JF_18LiO-0OCr?vjwL z`uTIq!y3lj>%XB-wfMN?k0Rf==8Z|I|Fma9+z0os*4GC1AF{E;^Sdq`0vn8fu>NG< z(mQV?H^|Tbwdk=*_gXa>UHL@so+Ur{qe}TcO$P0$d+kBmwW}xptk$s6AMf4#YUEdY z-__VQ@Ooz2o~sv2KYTaY^Ksm~#~(dC+wJOt{QI99pJdwo0`?yICjVlii$mYOzF%SN zh*PQ0m%Q5g>E23<8te^dQt?b;|H4Vmqu2kbEvYzu`t-qn|G9g~ql-;nd(!vk5791n zAa(OxPfchrHuJ^hM^ESd_N-&&JFRaVTd;7`+^S2qbZmNS(5Ht+uHKcf#pg}flTO*i z=}S86VDEXO>MnU~{Mu{Fv+Z8>A6}xt+R7T?@9LMDd8uVi(9KAv;~s=$Z5ewreeCK! znyo};szwTv0Mfu*(4-Kt71`cj``w8ScQyh_XeD!925Emg8BaQDF0S_PbeWxO*X$Bv=Rg^+#6vDaZo?0$lflPKSy9N|XDvXg|Ab|)m{6d~(T zUO?HQ5FuZlCZrO82A?712FgF|_#*{sPB=@*pD4r65wgRRkb5ZmVbhE|4`(%)tJrZ- zZbn(VBq8>r*9d7*ijW>Z6LJcr-*rM3mL{a)4MG-_A>?C}E@cTBbCZx~DEr@Gl1zC_st7VU5!*RUI(Mp+NreqTH(c2Qy{ ztsW4v3Y%}^UjYb{Z$#+(&;wWLM{faudw8mWu95L`wh z=@|PdWi^rq;%m!ksH>3}DAK#0Mn*%C zCG|D38;TtB*T}CJlGcG5NrEDmf;93Hia3X8c2WhJgoHvc&A44!SN+TaYfe%_}WDT2)(Hc2| zp@?jWA%Oz(TWRD|DB#;#BNae=d7IqVY1-++?xB4((m7ruo{7e?HQKt|iQ~0!z1UXD zoPs^Xo0KIw*-G(ioXggtUHG4<_)aWPNhwgt{dS@@K(qQyF4(VN<=e^H%+lXd7y~%P zNgX&lJE;0K`b^Pkdwgp(&>hC7Q?%X2jH#Nx(Q&HQ(D464D`A|NsuxIA znSrdn>@OixhumEhLrV7e;ZGe~^)9-L7UsfWdB>ZKS08909u9Jh#vf`?|7e=|@1`ps z{_Do_Gym1p4^4Il@sd7Pmm?F|j!F8T?QER>OAa&ef3-8C%67Z7sjwTf%zxd0$^W12 z*z*6g9gE~Y+p%c=(cVu0V-@}5f@sJ7@Sp8iZU5Ph)#uo5Je{TO&}i=0A89i*_a*5X z8D!VUFO&F$%zgWb)u3#y%8A)&_KbDLT7t;GOG= zq7y4l86!}LUSFXrWPK+t-xQafHlo)-qb4hUFxrV?xG3g{VuvWMi9*|?twGPVoA?dK zS#c=$=_aj(Rx)(EMtUC62)(9}S&uc+kWx~sFg50Up)Jh4zeW4JYN6Bg2kaz!h#&U$ zIjv|_V`LEZ&fWi$_M_A48yYocUe`u!zomH(=6un%? zG!2fVthtiuS~pI^8?xNUHE;4Wxz2xUYM$gG2`3Ybir>&!m-3u@xRLe^9c2_=LS41N z#_}_?m_gT5U(qmxH)ul*Z3)^tuc!44=OxtB_;@{aHeQ~go?5!Nv>lgRlBB?g>*;Xb zPa7+)PS`-pc)_n>Kbn`XD;}=n#g(17;wz1)d2to`qtj*j3g%!lwm(c|_>ZO~jPTLa z+3v}^3_zD}37jKY(?~8kp=uPhld7hpCwtN`TMZyKTsx&|PPlej)tpg7NF#f?kR9Z# zs=4CYIfNYYq8qB`)kSyIE~r`|)Gn%8Vbm_Eng?p^F)7G+qV^MNY=Xq2WE12`b9OBr zS|^YYIYHtvL1Jh=EK*2Z)X|}Y@!lp{(`gSWLE?>wWwdmafl>qsXT1h;5f@=}QKJxe zNi(i)qM_y4d>Tkx$RK&ml?*2(<(wI4oL)wK4FAp4wSg;_l)xqVNHPf^lR!$S8sh>t zmP<;2eG|w;W9VjVk1@+=@i?Xudlli55+Nyxl#=%*LQ)bbjT+;Vhlc)h5Vx8`|4SfWZJBDchaNC=Se28*DT`O-simNq}-3Ac66R>l2xss`H~&Xm#jdN6$m4h ztjw28nE5`0EM~rBY)X^aukq6|>Jc|YlJMgshHx_uk+4I!8Hb|A1P)PV90CHC8HXq{ z4gmqnj6;n4tuW(I2~dRt4CPv;NPwYS%V82=s50YF2Qv;;8V*$&GBXYpW=xR))i^*3 z2l!M1q;P+xd#3W99;h+gRAr1*&eK!1 z<2l47r*fWYSij5|seBW%r%7Yf;Q(m>m_`;!_0s?_jVx9*og5_aTDh<^4iY7ekp^Sz zk?p22m@;XYQ$w}Qasx?&L8g%<(jaLtNUD)Jg%-7^OA_@siFB@IsJtm1Bw}eBsdGBl z(%iq&If>?yL^?=_ohKcdik*j9CSC2E=^!wiG~gESM!Pw&M@^(2_TiF*KPNF9B!?XBL381omr; zn?l_T{~g%I12}^WFxXGVN_%JU!5*h-1t(?(SnOxp_zqgOA|sdqz`YzWgPXju1k50A z#vF9&703}XIYJYuVTjS_1TDP(_aYsQ} z@yH(qMF)}!QqfWJk-wX|4sF22jppJiN^zsPxWDBFFj|e|Xz)!Srh_^fe8qAZ&H0+M zb+keq%~5?N>S&JIZ;aHVAqO4<;E^Ok0*?XkND`@P>@jMt)iD4ct(M9dfQv`z7zNIZ zHOBa4H@unbDb!{kE0MxD(pVt%p~Ddvv3W2SNPTDqYHYrbg^K;DXlE$qEE)@xKC+!{ zOH4)4i)~BH2WN?}v3!m6pmHI?tMOzmo}G-71Vj)pjuXg~1jca!x1cH`FisH|$JI19 z-*Jk-I0rSy!Nxl3O|yTKS3AfZ`)D!$4mIzcIcEqyyZi| z4xJJRVnz;chfZ*}(U;l64xQjS8msowy7d#tPguxoudo-~dWiw7i=+i9htyXJ4TkYY zlUZc65fG;P7{&8w39oGIF69Wj!h)e}5e&7@LsZ4$E1yX~^CBA|96yMQSf|OnQ&Z*_ zdl96~@sp>$(AcG^yiJ5r+1eJ~ecFHYo6bdOGkD?i0q@ZtYT`$Nd?+r>NB|`Wb=XgTrQeyK2U6sviTsHkC<#sJh3rlW6oLIVYb?s zvN7KhNO4$#jb*kGv4{HDCxT6XyhIQ*kpuh4IWds~mq3lJ)`<#uA_tDbU83Ctp6CEP zQ2|c`a1tpAIShDW!AWGa+e6*#Y$7lcB7U00Nqmj5XIf6;Bue3CQ7iZ;ndD%BNy-9~ z9EeO(L?(gAJFTZAGRY)j#O{HMK3S3wVb)}jK-eZ>Cxb*1DT5l*c(Ss@WDrOofw)t& zo0gcY2(ayWvT=PP0ueT+`{N}-sVM+>s$E8%=`{raPqizmrekw7p8-<<@>F93#XzP& z%X>USG6f)`NVJ?6Q=sKoDa#c-?!bP`+*6?C9~yp*wFjUjTSWcw65-ZVPU0%+jKow< z;+PaT6l zp2h+COMq!g!)XdY^fxt}hH<=ybg1r}f2Z@1XHApivPd6tMWG9GOJwuWZA=wO0 z;t4o2N;5c#@{+_1MPddg!Db30H$%Giiw#|0cnzpJQDyk;Z*`6G!Sg1V15!rxNnM;zgeG2$?-?`CF*J~ApDrKRhCEbkL>7|Vb^)!xecKIZqm zLye(-%q(EM0HTudF_+Qo6DdPPQlD@cyX7!_!e!uGn%nLZZbehOPxxFhMjxR~jEpJN zyUJ`SNCZr?xuEZ)pxIoIpJx1egf=s3K;Kl8@3L zey4q|yi-IgbNQWn<(+f+ozALOa7&%*FdlQ&c+BPFVfyrQ)s{M!PX=GGV6%HJW_Kde ztck{sBbeQ6%jl1n2!wJti989L!%6HzjhQ}&n~lx298RDs?h@_hgve0@*zC^X<6{3* z0*D~!Qx1UKKOc!tIlz7i@Tmg$lmj%B0G}!iKXm~3lxuiTON2h+_jBRKlX(&oky3Z? zod?haQW49Wv7ZOfB;t!2V?Pg|Vym17&;)D)X1n<~oCnZEmH3+n(C^4VWB5b_z4IlG z2#n?f=6zB_&a(M{8BZ!n(D{I|0;BnWvcs1UQ1hW*Hm5cpP}wT2G#^m=WVzzY8tfPi?QE&zdXD*Rsn0xz|LN|r1327fu1 z7l6b#Bn`5R9mlDM_L*_$IIZr@eAFwnD)3nR^f|cv>vUovx>%_2mllGq6)r6V zT`OE#2+CHtv=Ef7(}{(kZAD89LEDO!7Q%J~PA3+Ew{<$P5R=jhmlisNOA8&srG*aR z(n8F3>vUofRARYq5iKo(N(rQz9QZ|0DS=c+EsU*zMSRYi;nE`LWaT&)K_}sfFM>W+ zE`Jfv9rjx+QAjuww3wrqG1+2{V#Z{PIY^uwx5W-1ixtRX2av@aByNcW5pMkwfFzL` zQk5kDNg_BXUth|l*OJngLi&DE+jxAM z29;(HDYiu{#ZVsL>u@QC5r+&$<1@5;;TRq{&VZjYix_>+(1ymMGqkO-?hH=pR`N*7 zu${$e96N(E!q1xLbzg}~@1LdJjn(YZ4RrF7=W;T{+adz7t)kc_itQp0%N519qSzsd zoubQbW8yhl%=J4E_aZkmYt|( zMyu1bh>?9Bh7vCSa&D-4vg>kgsQShi=V@In(Kvmc)(#O~`3m08U-nzU`vs^P+icA_ zu>wPuWCUEGB`YTqmZN6IUZIS=f*adBl2{=UVA&U_YZqTW`M%)X1EuIMIQJmbn3OLt zFNFL51wfu^ru+W|=7n%xzQDW?@dtZWeId>vR!Zaeae$RvlVAz3l4}wo0amJsw~}e0 zGJ-1sATok00dR;1I1FGVKZmHiN&*P4dKCvS&mmTEfO*E6i?jhh{#&I?u?nWJjulo3 zQ@ptdQwYy^H3TJ)P|0*P7qna&bhTo-nlBMEPqi9M#Ua6JFcpUxjOl7|NU%mS6<+Te z08AqdB)}Q~Oe5?){cPo}0f2Q#um&KRBno%4aaaS8>9UtI`9W>!YoOZST9}f+4hb5e z#vX5LusMoDf_`6062hPSlAEisyy;7>r6HfTUve!?pYBVpsrh{UQjN)%4w`<+v$Xxz zN)X|EuH_(2B*Yj`%Cg3oA$bm6#Xlm$7Dr^ZGScrkSMwHCLv&k#m{0 z(bA0Tmuc0q!fRcJet9HZ_FIR3Pqhf6;uUinNWTJ+!cF~#i;R?Azu_XIjGQa9SDJ7k z*Ygf7WQX;tC20nJfbuMD`JYisVl>(we)@30}P=i0_?kcJiR=PCwFKA%fFxp`gl%$|G)MVMD z%*Uu~g89-_T)2r(n6{A4R@x@4w8=*1L>$L$mL!A|xfvu5Yg^^~+zb+jwRTd=%^)F8 z!Zw4zVU^n13U?snpJ95O~8=KAQpl8EG%UH?w8#a1z#UizFeO$SvH|9i%0; za7&nnVOzK*%m>L9ZV7WDZ2^(te9zeeBJupm!pyzJIC%|c&08f%W4_04gM`Q_YzGOX>Wo4+Xj%TImF+x&i(~ImWS(U+E-RPIsw`#Ya#>xZLb*y-E|+Dd zcXOeTSYo+Q$U6Sd6(Qoc5}-K;_?81yl>pyzfUXkYTLthf05a8M_ge+J9cMQJ%u7tP$&PFQvXdht0Y{}o43y8(KY_Tt3+$ZmjMqyN|M z&+_={J9gGXXm4r%?{Jew<5Z2J)<@Ow2YpY~Y`E4})tqpxpQ<^d)?d|J2&Ds54Idz& z@v3HbBRV|~4$L&);ic0Hs#XX!^X+2aAt2M~C3VdMHS_Ia-@)uU{R!8Yr@aTI4I?T7 zvOQ4Ai4K&2doaPAXo9Ng-o%+Es;Z5+(22&xyK)`wF#_)3eN-pzQrBP+c|_Bk9afK=)$0y3u6aaKA^Z7@>D)ks=pKB$*4oJ!uv;76dM>?$J;uc0iTK zV+U;?FN}@%Xc=SmeVlV0fEwnTD9v-GgFNb(f1eI9x_^Lo7#8Z!5Suk_wm6>HI_c0 zK8;CK=6epq z&SaP#->W(CJ@mumQtc+{_X?FgE5A3Ezr}ILeyN9u0QUo+7&VVW_5+|8HIGB~1HhBh z+z)_abf5&-54DQRc4z#>49EcXLoFX#f)-Z4=EltC8?zmv$&Ofu2e?+lrB(;HRvD-< ztqv%y4gl1NW~z24xdIM2XmvnnbxVf5eh>g9shMv-2!K+Y{Xqbfq)}3< zgV4%scgA1lv^WT@O3VJPqzughAvP@zVs|b~%L-kMzkkKMetvt1H-q`{efbB@z|6$| zz!|*Oj3U3$Qo$wFQ2n4Ve}GaJ<`2Lu$1#7v6QKyB(JJLch`rU zztN0EzfnJ*GW@PXN*WuNLq@-c*lK?Jjk;DBvE`3kf|-r~kxMYM@jo*A7-b(7$j1N3 z1vEV@Z7jma!(7Hl$>K1VF-p~#jm^mIFzj63*z}0jFXT-}OYNfu87J>K%I|q!-g6Z9R4~5yomS_8 z_fciiqcEw(<0$80KPGh(QRy)*cf6E)407kuD4VeNF(y~(c8t#K#fF*%-M4jnV+kn!iQ$lD*6Bt+DDoRgR!NgU@S>{7YooCF*GYu zgiJRoKBYdo8=YY^cuFgmj-;!6Tou1;Gs{OQNCL-R`5Ll6ZAa6Jgfxh%Z z)YxF1R;r%{vr2TPYInlGGn=1=>J|6~A!;tfkIquET(PN`$?Ve@;0kmVscZ~>g0%h_ zNkT-`XSh}$$s5mbtv;4uXOwx)fJ7BV;tcFB9w}!)!iJBT2-0UT!^9&6Z*9T!{siqz z`!gWmM&+;3^c{|(&q@*^x;_gMPIR^;aTX+;=o~5ZtRivNfy7xw;w&e@o@>k!XF+YPI zmFLu~WJ7sQt-Et-(IX1-hJ&7u$-_P=&8Mpf)6aACc@p6~N1u-xlXPB9it{i* z^9uRALS_r@ypi?{4_oF3vGpKA@CzKkkN_7rzyb+yK>=Lg0Oo?bpa3o?07mG7Qtg6L zjcIm)Zz=K-Y!rHi0cVaEBOyZYiy%>vnkQNpLBf}QCMjJ6iE3(Zy9grHm5ncgNDV&y zFM>!7^?bYtA~j{ZE2%}z6RnFNQkyO(b?mebe!r06%Oy!hgzA?#na?HsB~E6csud)2 z$$`uzMdp$NnM;byC0L~v9?pc6WoEf#vQcFAkSgRSqvms3-Ok?ga+NLuE<0Sh3{L-7 zY;%p8(GBy$tl;Jf?y-WKE6~FVZmz(nR&a9#dRW2D73e|iD!RD>Wr&Jyu0R{ zh>C8mKp!i(xq|g!1vgi4+GGVcR~&+yD>!Ykf}1NmxGBt{n?2+gyxYf%O>dIA-W1hb7*td`O0+r%bu1QfM z-nqs_nbFfVE-KPyG1$ZVJRnWH8f$6w*2 zFic7l=FKuG!f(IMrI;Uuxz435fi`SOT~|`Bb19j+5%U_{onP@Fs|6`hoV~A*oepIY zW6Eos4t@Wc2HKwhfskxXghjXU_j~w?n}Th3{-fq|o2DA`e?k2BT!eQo zc+uk}I+}r+$?Q+wCf_$G1^!i_El+F9!?stv?S|B}GjDs%+Zr0@-(dYYD)*LO5{5CM z-ihuG`sDLA>m8XaKEHuBHrOJ1y1@r~shq4gFxXBs3^Le6xxojUKTZnqstBQsNpER* z7ZDrXm zApvf2fWu%fuCc{rKJIRDkcqgPP1IZ1HG~sz%K_vT2Z_5aK}0Ncn}e*BAh$WlD#`Y? z(&Dy*7Pl3^Z3lqc9H0uD&dkbwT#Gv#V6_Ce!>znVHzwrMQiz33&Uci^J6xpcxZJ@e zCmfeM4$rYW!fj)#gh7eO=PsZE>6a4fE}#ObnLfS?T?#3K-Gx4Z3j8j>gZMM*F2I{9 zujwwpgJrubKFn|wlG)SZE_PS$GZ|s;;I^@4$w-Lc=^iJsR+6{}5(fPWH8wK$I0-g> z_c(!M)ov2F=Rn||B5)7dH>XD=fqNza<}7iyEs^a5jD(23?t{cT%{*qj&q*xBRR(>Z zkE%I!?t_TCvc!E@B7|#vUlC#R^FD|iAfbllrx$C~XApM=TUe(x;nqlMv zAiPsY6Au^ySL6YoPs|5piaam^G`)1?UnPi$=YHiN8>HA@0kVK@G=@>VWTj1LWFz-0 zb$aAA+Jn|6o5RXVf54rW(I6MSlgeR)qT(l1r zVbRM4AG|PQmxq`J;q(~pVe{~zISu$cjAJ`EBO$`K-#}t6Z6P1Nzi|@gyB2>_B!1&0 zrbrUMK})f7{00(@_(EV>{$>PFy|kS@4j6z4-yQ+Loo>dhjOQZ&xYI3C&?7bQkNB`u z!=22Gj{s1ZoAD62s?SfBXnL*McXz5P3axK^69yjEfyr{cznCffe*ylMI2@(4J z&P}~dlK34Y!svEM;&+f}#KC?Ci7=Y0+MP&a*oNl=4{F@G+!Up{9zDl?@;Bfi!or$7&~g4D~*x;TRbyii#vZavEfM=Y;lMj3 z@Dl*fqY-i_p8(j(o;(4#73n+yxQNT2r~zble*$okF?s@UmN63GPt**0&sq1eiXHsDi+C5{K!Sp)` z`iz6_k)Y2M=ray#20zajs1f0!m(j)iT)sAUw}jojg~Xx1)q}U&i(=0(4REpMq#~5SrKFX&BZWZnsxn~i`isU^w52p z#HwS8zcGk0e7pP`gV;?)_J6}9-DSHgdTf?^%HQ}>EWNn>jU+6>vo{>+nnZfTkqUz_ zTOV&Qd%AK#Z#dZ~+$q{k;5QDyZxrwwteaSRT>`(sy6HiC(irw@6l$fr*;%l_tR|wn zx15CeL7lgp#0^R5Ehk|*6K^>Y^PuLfvcOvhB5xIux15Lv6k@x_Ta$?4(n|N}!=e*L zLPQhcC#Lz%#iFb;?J4Jvk-gm^9;IEg$R}KmU5t!ry zp*Lk&3pT3xKDW`$_RZ(e!@ z0{%U`eT2=j|?82jHh0DF&}4s$&8G}r{G+Sh$4D1%~cd`qHyQ^wL+pOED8^C z%~KR!q9|faEUFi)iEqaPnB%de_kXk%Gb&XDT5(bM7y-B$-8CfSN&StQEL!RCaB^aw1`o3d028!=1;)L1rzS)XV+5ubV`*x`Ds zWl1!1w1{So7Ml~qco+j;joFp~h$v6v0OmQK#sSQ8JPiPGe0Vhu&|3m)3P4i;jF6_8 z(?QeNbhry7HtRJ_P6sv{jPdn!w<=VU@C#>pQILqGkI*J+Y||>I8`;J55@BX!KmjWD z0t!%Tv%%Lk%gu%YG=bvFpg1TsCf0}JqDvqV2kIQ?i3HN2Z450hA5}WE6#zQ4jiFPd zwmN{tE~h&H>k3#0a8GJ}bV-M{)@JijeQY*t&N7pWIM4M1uH8;Dr%0*Z5zBt#tO#4TaI|HBC+ zVyXH54<}^_CvFMz?H^9c5>DI_rYq-UjQ2 zay6a?=%wp3J2KTpl;_6pGfzp~_Djh@3ec!J4HmqzM8Z*b%Fwnum``>{K%3AyHgE> z2O9|WZ1GT&z=KZ$HmMkz2PT1dws`Of;0rW10X#4P_`r#=Ge-{JXUf$OQIaPo<08p; zax$){F~OePdW@teCt?OFo{EU4BEq&!Pd+?xUJ^h=LS7ueO#*mv0Cx%Cr2xD*fa&vk zDF81A054-{DZTW7A`(D^Jw*TzLn~r$VoZwwAeMSbx2OmJ#7&5KsQO2g32#1OSW{5h}DGHdOv?h8m(4v6puSTsXpi#?(pUhdFHOcsr6PCP|3!sTe1LZiKx(~bWb@6J0=l%b zt0<=g6yi}1SD^$HvVxovP{;~$N;%xq$53@kDS_61v6EqOcCLYf0!9L%mgv2RDYjqF&lZtb&rzK{yI* z9hWrrRnSX!D3qjwR?$x zrZhyxQuCy!G(^Ty^Gnl8bCHaEX)bPx-0Vs#aitwNmxkTDBV=LORXcM(nJq-fQij8r ziQF=PX-&=Vtt#Wdyo>|$GJp~vN+|=Vacbq30n`C**D@I1_o?~4Rb?=|!i#W=&^@}A zl_W&SQkI)9RPIt`If*i$$QDgmrE6JEpu5zyEC`6tnv|6UjOewu8HWlSpriz-zyWHg z8hiAWl5iE2*a{B3D{$V%8$aE(i||`3a+#&26nw`MNY|87DuVPhu6;$29zsn!SA_KG zvYlDQBwdk7_bJN0@8nc5b}pHPb4mOf<7VK^Ub8Ff75G~~eRctQ1&@3oIuER)Rn= znJYoycv@byo0Gf}pDgS<#n~jUWZ0`AH(jJUCX4XA{kZgsQo0|P?klDEDd~O=()}=5 z1gf8dbU!XVjyZ(P9>V9Y%mFG%fXW=ePXbg{0F@m8Dl34>4gi%U{TjM!58-uJf%I5v zep6Q!NN-II;Ip+=1=6i8xe5@hEx8I1#Ku+y2x4Pn2C8DDRo6@Rt149xE_ziCvOtQh z%0WI;wSpj30TN5i(6_1rspgr#C@0^ol;DYbBq<)qZY zJ(iPF3#2S3r4~q8PD(8hvz(M#AXdOhsReeHlTr&NvYeD!4o*rf2PdVLgOgIr!AYs* z;H1=Ya8hbHIw`e;lVWF{EAwWBlTsVHEu~%MsMm&Wt7&Id<4y{8GB%R6`P7=o_BA}+ zYO9g2?J)AS)yUU|N-R;!?Cy>JGS6UqP#-QebC?+k;n&mwi5PravH+^XNpz7@ua25} zbvOYtnOR2>sN+DOjv`Qp6EM@cbxZ<0tI84`adjmL;R)3R2`iyl7bL8NW?e<1E=X7j z&AN(2T}6Ve;<`M?U}ye0(^B|A^#HI~mLo_8?;r~r_#Qg#9Vno#yYNkaH;ftv@wkXISDg;7pO=CauQSIvI+zVv7rV!kO)*H z0ztw`-v$1g1am>yaQJcmE(j#7^j#20d_~P~9tr{pD}5IPB3Ak?2t>rD8U!L%`Ys4W z2JuZe2t=0AZdj&leFuR^f%ILlBq1EaU~UO>R}Th>mDD`L4_1~4=9Vyb^@0(rGikymRV?-Pzq1Ad>GS8KrUGxKTT zp7327LdFu>UGB#XxePO}){x0i0bfHldd99GGp`mV+*G4A|YeWaiUy5m}#5Cn%%=s94l?WLK-8GgnkzERLB@JOG*{X-chI)E z@idSJZ;@m^f;aKWJ$!o4sM=1iYlMgCt~_`P7Y9%gA~uT@u~`(4#*7tV`ZBGph|JoF zqP-|Oite36_s*iRizvE^q8kt8e7Zxye}-~B_$95U=-7)FKD~KI$LK9i^ynivz9)*l zyzuE)KroB;SZXX>q{bp}=@#t-!!fTj0!IDcUS}lkvAoVm++%s2kr)We>x{%eSYBr& z2E+0?BQY2Syv|6Bh~;%gVtQC!XC$VFl^To0^srK6kq%yGq=VNP>ELxnI(VItj$UV^ z@H+cNK{pnY39mB>x-F%>Z>qbt z6E0;7j$rz=Er768`L!)zJu5D2;egOWA+%r!Mt)P3DvO3lD^(T^kt=CUxlE(ENVc6s zb8%DT^E_IKi*_I!jd4(^vKVO_;U>m#7&BEC1DF-me9vQy1M?UM<}rX05oHXZtW;SH zphT)H2E%Qo%3{7AgG1N?zwd5q0%RR59(zPWgV5V?df`CYswNwPy zp4U%(9}58M{UNbxsAAPniT>u1Z7l4!l)eW!%;SlL{TxqD zQ(8+B!vAZ{wHzQxv<8Xgw67%58YF}^twF-do3vJ1w&q&0ya}6CtucsVTW8+^-5NyZ z`{~8|wUL0r*J}enD;LoQfM4Q!mW6;eTx;`vA#DI^t*SNv6*H%e!@#u>xrnwBMEG)T zIf$8yXv;yG%9Ltb2avYhyrz%eR)Ms20BI|75$z<1@aNj`@#`;@ZwHXIbd{Wb?bP_S z<64;hdpk9L?HtCh9ban9i0xoDD;Lquod3*k6}gD^l7w*l+JnRww4Wr=9wfd{UTb@h z5V?rEMq?y;T#5KQ#H^=6ClD*}ROkeD)>EMqOk_P3I>AiVQ=yZ?Q=yZ?Q=yZ?Q=yZ?Q=yZ? zQ=yaNQ=ya0MRbO4%=HjYh0f6J8#+iDyfbwBh9;?6!KXrJKD8#wO}4Wd`OXd_-&u`( zXQ*W5B08HZSL7nPND|_~(S?&3EMdEF63M8st)PpVdR;gHGZ)cC5$NJTpo=2Vg%dDy z5nW6IRxYBeBq4GUT|vUiMRWxTD;LpKk?0B%RxYBeBGFZmVB2q3k&Eai0mMV58vxd+ zTtqhjtW&v&ZUC_S^lkuIr*aY903u?jZUC`z5#6Av$VGI6rdBSZ8#FDDi(sA@8*lND z>CQ=*xrpwZgqe%z4iX|4(VY`8a}nJYf$oX`)3UqBMf8vW;yKfU1DLsp9vr~TMfBiW zvTdOU2Qc@k9txm`0$^j`LuuH9YiQ;odYBqoxrm;Ugm@P9_OSh9fD=bp3J>Lq(CkrPLdGMuQ+ZAGZzsD5>_rEPFW(3Tf)pm z#3@U}aZ8xFh&aBqn)Zt?dfXxE0n$7gVx z|I9_aCuNIA(tBLCnTvRj%YI|*ZBrl@@t(*<^p*FCTtr`fpP7s3%kMLD5q%jaqj}o` zxrn|Z7s0|CHhLl#(T~e8a}oWx3^Nze&q1$#Z1jwMZS|(*m4igP;!V!%D_jy_yq>fM z{&#{shEF@a0gnLtiy&)&DB?wsHINs^>UMe=qgqwnQyU~M4;Gj4{fq4Vipe7W8^W&{ zf$jAf^NZ*W(LlOaCB|{Pw zKq3IFWJn?aL^32109G<25eBo8A&D^BI+YAbgwg&Z88S$c5y_B2Tw604GKgzyCPM}( zGK09b<`Zg=(sq!8wu5*w1fR>VLI#T*0sH3E>ok$?T7D!6SpVA_OvXKyH<*ljEN?Iw z{48%U8T>47Fc};zZ!j4g3wVRcAZmGo$*`K`4JN~CmN%FTt64dMWCw3B*})r3cJKz1 z9lXJ0M{h7$<_LyBH!DXl1iF1ghsyOb1iF1gQ&g>>H#h{kS<%c8=q4UpL!g$GBN!sW z(2deca8r-H9_be+l#9G51U3KuL5 z0BcmJp9TOc)K3F|2=&tdV1@c=09eD%7}5Y>h5Bh?1dH^<>AUc)(zzYX)Aw{pw<6wj zhY?J77{PQPh=@1cL4|Y?@eY?N2;XTq2Qeew;T*(_c!xWH341jz?hspV!0T3(V%}@i8!L=~G#0&t4nVtav>-0T?PaHPUGBEsB#G7IIMJnR8 zXG#*nH_GHBQYDE@kk~-eP-D-COhqCSBrNAFQ<2C7iH$T`&Yny~A`>Jw(R9dR&ROQa zNW^7H62gDV0tqYZ&H@Q5?9KuS5q4*B5~hQe1rowT%mN83?9O6gw-3HLt{xfWLC9=P zes!F8FMXWuoJ@?_z4ZF{ueen zx8BhuH%up8TIt5}HQL_Xu5tQoTJsL=1!J;I0b_TE{-3|O9)0y#SM;AM`{Pp#|IhyR zLHbc!p>6m=Q;z{UshT4H|X(}_v!!j z`%A7iN&nGf`)s`-HKzQa*D(_2>X+E(P4SaP^7H$noNw#Ns>BzcSdR?%hhXuO8=s?p zu44{8X};aipWECnz|i=*a+t5uTzp=o$X46$6xSB(Z*)DG49v}6roYu~_>#-~?W^?d zuJ#rrgfze_g!tnXMCy_V5`(`Y@mDYjBhmP`F3J%6w?Yl^S0w(5=6xg3leM-$dlUw6 z9PizLgpvTX1Vc(){2hwFLb$93xJyU~#9x7EYe9mFLm2BGft$n7l?iQ;8@pa_T*~Ng z=wZ3v{h*%g{>7V5Lns2@;}>Wqdg-nGwq-4m(ZRV5ZWjA z+H1YClkF``u+3)cso8tNnrud~ul`I$*$1!p@al_K0$!|r0Lpm02FiLOO7;ckgYinj zD;cjLcn!rX1+QUv^~Wm{uXMbIXNVI=QL7^IOIPC*dT}Kd^3#plFymA}lO8BBBKy?~%|lB`tnHN+oS(m-GPx zwX~Q4t|^&`g+GkSNE}ckYe0O8PsNTIiM|Pm15=F0Il7DeT-S^d9+AFXPj>Dz^DPaSOYaG&PYp>sr3+ey)7ini<0rBmC5MQE=DMY^<#j_w*u+P8@A*{^Fv zWOm!=E?px!cbyn*C$XtniGvd}d`a~qZ}(i=^k_Tz^32_B2Yz^RgzP@E<N_|ws|88wnmr~xu|`6C7QS!NCA^MrLbmf!TTPD?cV9vxV(iH?s<(7X7M|<1&KqCRkAsy_l^i3JTkFIS_T;!pO!YXUY8`2n3$DWFDh+B z;nXbJKBQPcy@&+=gxIXajcyh7tjzv3l55sW4WAvLSHIT3i|_kRx5*i&dUowY((rmY zn&UFu_Dnlpv3masFA6_N_O0uCGtOU&D7&wh*VHQME*HwrclR5Xm{~X>e!1UX&96s` zHeW2&o_hFoj+&@dZ>}Hn>$Fr0D(cs2uGZ6aLQoIas2+!%f7H@Ho~?O=yH`K52=Rmp__34d2|v!@WmRa>12X1%Coi76?WHHtXb z$#W<5x(`Shk?7mxuV%h}18U564&8prsq4fAC-WOVZN_>**KWly)>7XoZPe0Ahd=ZB%PZn&yi-6; zFP{fqK8d40cQ<|?V=F_4xEtnelb)Y%RRqumPzF zkt5(B<@OnCTiGDzi=Rs5rtjD8Yuh*5;9m{Gp1t1~v&Ck2ViB<8V|Tux_h*mvu-wnK z*#?Tobb+=Vwi=q&FZcVMwl7_C$LzQD(v0ILZDGcn1GW{OF8GixzODn$fA(Xf8+w^J z=|x<1xM3O^bC&;9+<11-cGezIibS^viHQgd3&j&6G9avOa0rde4vmTot?M5`!h*ws z8-|94(uRjW=$4t7k=ci|?b)kOM0$D)G9YU}pSEcO2auFL*v`}YL}!m4n3&SAo4yr1paqILhk;E;d@uCb?f1(d57xPRBt1s)&u$w(`emeog}oj1R8 zbj-%+7O`FZ8fF*uU0#%6<4DcQNK2`hA95pjlK1P7(dGQf$4>prrQazR5EkekMf@XU z>IOB4@+WnJ16oAYZ5T#cgxTwc2K%=N%JUD14vY*9?{u%+&DSB_BcuD+ydp#TYt@I8 z4fhNuC8Hw(2!owJ*Y&6N+~Av@7qz#}0r}4P&NXLyBpBrm+o~85 zhi&*~*3KmNyTi6kPA#Lc7lpvRi+~ds1_zJ1jFIr-!nm8qT*nCf#hk)Oew8_v%(r8& zhTJ6#Wo7QRleWiNOLiY~2r;_o&z!~}IHat`9MAw@MR92uYmUGiN`L$vgnt9zJqB`= zVB_Iw+aLeG7ERz;TZy6_z@q{F&y7$L4=Ew|?xS93Z81e#{i}H+YmWU_v&%VKqoS?< z)!dmixA|A|;&Zm}qHX`x{5xxI_pj#W=OLv1znVWhZ|iORa>3Tqm~p{|4}2OC7i}Hp zr288w7i>k0@Qb#NbJ7bN;TLRm=A@T1HeRsVG=J8ovHjBMJ--&}emr(cy@xZqzu9?? zZ77Hk$frA=KlWO3yv54&-N94Oysw${^H zn_KpAvB}+&H=FH#!AHKhTzFfnZQV}JO^7{I!E7IO)a}GC&Bt_)F&5k_)b~W|Ugm{` zL#rL?@cGKtANx0Ne`Mc~!e)E5l=f%3u66D3UBxh4!y|t!H``g+5F2eaNE0$%8;ws8 zliWF%Y-hFdvr8>n^i|qrZQ~$O@-Fh9LB{fJTJzkz%QkOnd+70-o8fuQ=4-sXYAa5= z5To!l+grV6&BliBRa=?dYCqfZ5J#i^!F5|bt&>sehOIuWGuVi|fod0Hw5+a0m3AV= zPd9AKallWE@i%Swh9b0t+~W5o+~W7;&bwv1O|@RRWA55M(K|#1M)|i0_4kj6_75)j z^7C+S(J`{AUsx#i>A(h24FeknhcsvyB3`)KGODRxXhdkk2GJ1>LxLj0*efC`x7!2T aT5bD7+i9C?)?jV{J*TKs_0>;o&i^0$tgX2T37;2-15{NJv5gfdmLeDI27S3JOHHAXQXA zMLI+j0thN12vVfjD1xGZU_ntJ-+N}}&dq9m-~W5Q?6bL<*}3O^&zW}4ncYpn@0AK} zR$4feml$T=a!1W=dGn0LyqR%qM|0kq`@MTEcS`jW7mSntyp`26q;R}*F8^s%;or`m z{CZt}9W@u#D?5Jm_%+b)&d4`KUBtwVxbFD1dNpo%?(nI#$Gh;|T0w;mYX$5$6q1%u z*ned8!d)XH3dfA>vE%2Fqj=$yqo)*B8Qrz8|EL3nb#lrVUK*X<^%AShhA_tNa&N|_ zRIC^q6dS}m%LP$=im0#dRzJuXNo{L=#bLTE2z}$;pg%M8g!j!WW%mcd&C)Ie1 zUxkrhKXBD!#+~b67tFlwe2Xi0Zg}bEuATO5>lHuu8Z+bjB$crDQ7>2!6IS)p*p4;t zY)9R{TdwpG4aBcS_}u`{*x~?IC&I}J(4IY-V!S(`Th~{5SAMLdQ}kmWZ~NGFa%1(0 znYB-QK2vR{_nD^xYjo`Hy>4DWa@OVb^PYXR|65l_pIbkte6=yJFRhZgBJ}y#tUAj+ zc;kXI^~2w%|M~gyJud{r)V+Uw^@Q6`e^;`9|LS>P8?Q7xxN~E{uE(1FdZya*YaVkY z9WMM~p?|`#8|N1uj~&;n(fG5KmOokaXK_gAuo?HCWv=lRxAkD(Z1{Zj?Cc~Sd@lEP zrygd^@2mU0=&ZT5fBgjw{hodNz&ncrzN|TD-sRvKkFWo+*%RxR_P<%d&o6%c!>9fV zc`0T&E_hUc&c4^awx7J=-9tI%k^)Ir|j8#=eKYEY&U3( zbHPWuj=Mhl;pv}3FD4Z;+NP{^%InDZ*Iz`>Ni{Z$*Wz*%z46uGRH!L(J2)&or1hZtWaCFKR+$&$exM4*ayGtb#GtuKOW!r<-rHX zjxX8w_OVy5B$^lEggsaM|~U$w(;IZ0dM4%ff1Vm+i?Z2DW1D}E|%V?U@cgbnnyt z?Bv^fTsOX$x2naT6F+{xWa~#W-WheeVfPu+AJu!ORlOfNr_K26-G^t}og3Bd57+3T zi6=LgtiHdq^8WfOTf6p0cBpr%%5d*2Hf6IvTU~GZKYus;VAB58H&1o^`yQLNw25)? z^(Ut#-`!vB2=oFxzjQKqajQFth4$T^QXZ(e%;*S=kxrG4mYZ@sEeAg#GO($EJV8SOwf0 z^f6;wa7{eQ*cm5d&){0lgRvH$F;V5|lfj(R5<+l=c0Tzi&hZ1ES2)dx`TQ;c20^&1!d$N|%=(~SLzYm+mK?eSym zB(B4-2qvBd5nO-&lCfD8vHF~6Y-b>2Caw)DF;?vYW9xB!2G??xAr#kKTnAlb><3&M zf5q5)RX_mOo>duZi^cW`t}AhET8%N+u5TFYj2$uVTY%zP;XB4w)PS%{j4i8)of22C zT8xdj%-FBEcD=&bx!R1qg=?ESjD=ohYzMBM-!rxZ=3k0ygL;gGTw`oIu9tA_3yZe> zfw4_kZ$H2_9LssvAMrP5E*5ozu{W`fHuwpEF!`&v`oh#fKQmT{YsH(4&4$TG;rb1( zCAf}<>37~@EDR=Jahowen0)RpjNQjI?G9sSVe&6=O@_&L-bFi@I`>z`uHYK>8!%w$ z!??Egb3yyx87qRxYy833e3-i2J;tU5Fjn_Z#umZk_5MM>!GseYpnqYyXCE^52Tb?o zBgU%3Qh#C_83oHc$qjZAmO1V;SS&RE#=~GOp!v_92I~mT-}W}x18AP?W3UxaG{3yT zK6XLFBNYr*6B-5h87vJNZS*(T-_XRUXt2J}pn0IdTwp%GlEJ)xL7DOsn-gc zLX-T~2HOZtes5#2M$lwtJA>_lCac>U>=ZN^4Lh!Z>0f^g1fj|HP6oRUO&-J=ECOB7 zKfz$nLxBmM4Yq*>W1_*1qAQwpL6<;*g02R81q%2)Zm_x_{$jVH+&trp3gr(zX|Qin z4YoYpFc0o9R+v2&8UaQ3rW>)2O4~W@^2IEW)nX2|o#SC9&omOf#GfcEDP6c+s!-JY zStHf3+s!I<)8*2I=Ch3#YwX}K32-X2W{k6)TtCb&W*bd?ci0ttr&(@}vDf@#j?u>a zXpRwKZrfl~H529+)*%8>W-9=9K!>>=|( z9b@lvbctwVp!`0!AD)694Cq$-K9}`mCc7>DC1pAwcMnJRvf^O;>0sqi+`}sfVdw?- zo6NB<7%hF>xUdybf&MHd| z*|)5EvZ<buS&#YiulivU7!&GWFUWc<6=l|A;+0vC ziRfN$W-c)H7)DXhOU68-T;n{0-JM~u2}RppHXb@Ue!ww9^$^_4t;aq!TxbXubIe{n z1ow06aiHkuLZfnk*Rg?%Tal` zEiZvv@Y?5QE4myrhtTD?IYVC7$;-!d`P}@8F2_v2t)fYkybPer=jJnXIb^P;%VG0F zdATkxKHEfPxV-d{mr2`<4QN?+yLc_0E*}+TZZ|p`RS)hm*ws%Bw%}`nRr|$YhYZek zl`lH5!)Vp8@d^GhR+3^CEIR81|DTVddKZn$9_E>^5cvgMF*4R)GI-I%D~5l?#wTG? zDWfqAe3JjqN71{#8RIIUeP7kS+yBwNix;m~AMG&$1jo7mNBfr>@i`8(kH&&VI=%FN zwC~uAPvFKpb6Yq+>~qhTv!g+r-3&Kjo0UZv(Q6$r&=>#T3}nJUHHsca^P^t=Kky>l zL`ylMcJ`zBWqa-dt&K{J!2g5Rj1GKyh4NqU4^{g{rg70|P}DS;f8uR;np?wpW3zT2 zKDG6DH2Ay^XT35x+w?SNHDBcH_A1W$ZRPB-4>^10OU|bK%vnweXWmsDtU_Z4^KR)V z!tOdN*nB#I2bif7`C4z1Lj%CfIcM}RU6H)9`T02`r0Atd+=G|D$iGxXm|47)*D<~} zH&1ljFWU7qe-P?B3^)3-IzmFMS-hH?jlbcQmCfRz>9_oUJ-#cNv4(%++m;MPVlMIf z*uJRahT*=;{C_|E*f|!<8k#rX<;h;~Q|QO+u$fP;R$y#r-q`0xqQ;-8mkfXN=w{wP zzc}h&FM4j_U0NJbM(`K+=ejo$b$OyLOQ||-3va2h-`m2+`M}|!AHzS$jNZzld^9>U zb5V9}wO$uPV>p_=$KV*LlEI4D=eopEI-yGrw4|+tEH#`t@!CmU^1y3f=#nQ&2xnAF zFSduBwn{GMjTg^YMOF@_v%2Ji(wDka9;I`-Q~{;)y5x%z?TeC(A4(Tcn!$ZoDy|uL z-swcIrJ@tlSxYq&Qdt~lNxTF-EMIi6G)B9eEIHA1CQ1f2pj768lC1ZHK-x))(KgjQ z@CC0CnT8^vuvlu6CQ#17w6er;>v>%wkQ(OoZM<hP(OprLh z;QEUjGeP1Fh5$ea%!Dd4RJ{}R-4#$K2uxD-o@}xpK(@*>=kMe-QfNvNKy3jqQfS#h z0gMz{QiMi~M`~M*gsrkfDp}TB8jfU^h6FHj=`LQQQ z28L~@Y;CA)=wTZwd+Bc2iB>1FQ>c(XO6ZZJKNjHx|YiZERNy!dMt&E?cb(G8P6Ii!~^n9_GqDyqt?R9qRdTK_*wwZl!L{ z1({^tO(~Hp?1HFUfaVI@bW&t;K}Ig0xgaB#PqJCAUi@-FWE^V^$<#BsR?oP^aJB4hM|lm{ZqRXxF53sN44Np089YD1ooH$m;itStdjzm0Du#M=>z~AU=496*?R&2-crta?6n{tgyhbXuZKTr zoNq4t01NX(1=3Q0OcWr?l-P*^WVtSt2AK#DEdFNR2Rv?cD{=EA+?>v8D|1c4&B^>B z<^-8#lJ1X5f?c69*Ceo$^I?+Pe3+!?!z9dy5v;B<)g-aZhfG$iTMOXH0=S+6o-Ba> zF+1<&&1=op1ADTTI9W&xGUxB*4FZM(?QTv58Qa~Q3PQHKIThO5?&efj0N$nxuoAwsyEzqv zYG3hmZG24Ay*UlKq_Ybcq%@VLnGw^lN=;Yj(hZ$1(3h+JoG#E` zMTr2W>w!6409y;ibPYV+4S2c+o-TkZiyjSxoYFf+hiTX`W+)QUX`LZRAkY&gpCL$8 zMTtnv&?IIE5(!HC8JfflHxe^6i5Vb~#i}V1GyX%O6ZP?MJf#!t5+vSHGukCcRL9LU z3S5GOHO^hq8s?+@yt(s{G00)IIKXRrE<|!Ihnsy5@Tl^&Sq#FN`D`AWXTEfR*K;Aw zj-La@9|lEv&*E<@$}2E-h$wBAsB>>OyHq>GXQJJlGV11vy5V4pAJy(TQKw=#v)MuJ zs{*+KW3UkPyl7wn%DNZIsC%)Dy7{GrE5HS1)V)-?&ZQc@T!z4fWz;Pyqi%6&fl3}N znEnh07x+0~3>C_~QbwI?iKukfcxf4Rrl?c70R^&5)G2eSy5(imy;?@y3R!3F{*X6! zAksIlf5=-#%c!XU!w%7w8fXO=c3G?@N;LKh^w=-JkV|J#W{*R>mWx)=0x`_TiA_-i zL(KAjW&&(Do-!Vq3GsK0izw4Lo(b`Hjjwdcf#ua2)iVKc*Py!zdM2jVbwl1mu709g z6J|0m7kfqt^G1{JVRl+wW@3K*W>}Bk4e5;0Kp&2$jGdkpWWGk31V1at98-dyg|0F< zdsYzXs_QKx&tjev5lmaMz_YNxGi(zy$cC3dkE6;1oTWfzKs8H%eyc!d3DECQA}wbD zbgCdTOMnhnptH30vlOV+9+>6_VOYVgBgZQ>pH-&jGHi4#0Y_rY@K*7kFAA2wBEqa|H4oa3vmd z1acjPJVztX5y-@u7|qdZ>l~p1qSvcR1GtgS9uk%)v0)+hlw0mDO* zmpcQ;Ui0`MwzaYeuMlWdnXePg4h9BiMLTH~M z02#QwC;%QRfENY8BlFuMyjuM>O5TfF-ivPXUKH{M(jGfo$lI$1-FzVrXW7EQ z^95ncCiBG*oT)(OYmoT@q>8!vQyyX#?%{zUwBr$ijJXyFgnbHOfj|g0?|sT!^tOi2 z0`%lFFtLuGF~Q|RNgE}JlF=0%0Ngc-m8h45s8D6ymq2!^Iq4`58E%Pv>3@o)t(L^f zIO$~}cE1w)vJmU3OQko1mqo{!_mA=p=7d>1FqHOZ5+q}xg+kB)b?ZVQ=pZ*of5sm( zTOQ?sEokee<}&(OB$^|!FRZ;tG(UtA4VFbvXR`UzXFS^6ahV6E&<0O;%J5||?o4O( z9P-Y^xHF3dp+t8s#+`C~Tnx79SO%`QwR_jwmAt>h+$D6)F}i=fleb8qAL!ndT+Ldm4}+NG8JNF`i#BC z*16a^JYHAbPHqa3X&Xz^;uS$ASi!#{$b{%pX)>?4k$FXvdBu&)E1JwJSTxo!dUqzg zhd=-+Hg06dJt8vg1eqm*%wpAPO9YuvkRj7Afo0?pwgf~DFr3|}dJnaqE&-9LI>KK9 zBKM4sNLC~0xdd$P8hB%eFwGK>nTo_fzId#MWr|rSTWan-!NXkSie2UnfJ?EV2~Pj} zbmg)N8Oc?%Pbik*9y?@Q20iSMaT)ZmL&jy$#SR&l!Km-K^by4}C}hWs%b<`QGcJQZ z_6fx@=wqKyEQ7vw$hgccWL)MJGA?rq8JEEh@3D~=pbKTSmg7oUEg3T|hfe9Np&A;? zp;I~w(-&aFa!*!h zfE8{4E6n*jFu_+U02$V;6aY;Wz)AodVoi0av=%D?VxLN^1c=NHt<)ei^jD(i4~q%D z61{GpN~}b$mpYYLrASC8e-%g^V9gZlDv-EqG*?=#f|kqa<_osPoIdyW0)6k)3c(lts2HPR- zbdTwFmQlB>jJn-r)D?+3cZ@xv?hbx4R?y8T5i$JxqVf_JF;uF$4@8}6sOt8LI(LEl zR6BF7fhJIY05fvql^;Pi5socly%}p>ojGZ7(bSGv<_p)UQpKQ zF|-b2$UaS3r^mxOj0gKPWu5yhd0ml^QNrsWk)1W3u(#bV>4aYe?Ip8p#Fn9Eu#fHwdzm$lKQ(#Irk0AzwbCV2xO&k0g* z0OVu6t-S#)|1sKX36z#^hZ1eEZ$Q(r<|})6#gI1@3F$e%DNNm7-Sno=(ljfa=dHy7 z?VBR^JZ!zXM>@mn#XTL=J?q6i9d(HoF{^vlgSdV0xL$Y9dN=E=7a*<;3PgIy8-)4a zfWgW98vv5U-c;t_pv}KQnBR&~Hvm9xC>sEf!L0RQ11uvCtT&+l?Hu(6tN&@OG*|9I zAiYtMkWTbQq3L5vw~a#6PP$Zjx!x!=wfwP-TGNe!2*pk`J~rxsxY2F7-e?h#hsbX! z64L#C3nUJ(SOxnQNZd8zP$GeE!4h)0ehUQb<@zlUkjwR3AYd=oZ^`BQZ3Q45@wbJR z@e1H=p=E*scw3wLZMVLBTWk2X(9l}0-=^st@{W=({quK({LV`LJ3@YM`Lg^IxkNLzMI8J>JI5NzcyPPNF&Lm zvtL^jW9d+D0ijQgooYyL0ijQgCm?`2atjE_)4wes^Qq2!Z2=j1`nLsSa&_iw3&=bW z8L=%OvYho$M7Ds42nUC4RoK#h-YTrsQyF8cFot#hw^bO!a-X&eV^|}3EAYpODYzB* zX<|yzini74^&L*xw<(bJv1Flb0;HD$*(N}GD+RadfwWBkSdPUu4X{lBSOaOB0B~(r z038Itb^zGteA@wVfb~%T+X3)USY$f@>~p^D09Y?H*bV^uoNqfUsGRF#)hs0E8%jodTe*(sri?*eL+4(~zASV5b|vP6mgFGh?DUd{pKm>=kaF0kp5r|A+ zJ}8mkA`ls`>Pb^8axVfAneHnBk$fGw7h&K`L@VK6tKaf;a1UZ8c8(7g%!1h-bNCwG zz(uYZ<3mtM*zbdh!BcdJqcl{P@CScVmz;R*DP8iwYr}NO6Q$w0n(u2ZUB1)fQy`J0+4~_ zJ^=XeQ3_xm0DSmpC1@W2$_s#f0C;31C=K>O10PlIiEN4GMC`-(^HufUXrBW)G!gcp zqy4x)_o0W22O$4IeO0W8$N;ohXgWp_DHfWJRYZ!lro|xQ#jQ1^Sevp~Yf6?W1`%&T zq!_DbMV_mO6oZJ_{5r20Bje5e0y9rx?iZMJ>O(U2Ys~!ub0#yVUgx1T19`bp4|=C+ zJX?psIEb73uk%*n`E-~m&ejedBo=*j0OO#ts`tcSG$3h89l$uK!mIKM`thn-gsC5B63EE? zAdQ2re4H8x2gN`bj}i$#s0YG9fO_x=y52)gzk_=45$Hkl*w5H+K2!)YKK&2~)wp%g z@gV@J@jqcB0{9RB)dl+x0Z@%6D6Kw(R#v?y{<5aohtR5qYVXZz@_Z1YY4#yTcLiQc z>T2Hn1wq3hMItzs)|*3ugmvC=NRY73I}QmFmfv|u5Sgin9MVJ%K~tN^ArPr8h#bN+ ztI30)5D__K5ix)K1@Ani@l3XsA@pHEVj?&brNe@Rbs}|zRg3!WHf$M2$`XT92G)bir`U6@HUS$``_V}>9fCLjK~oCGjV5uy7Mz}=S+3y zXSlPv8So2|-ej21gjzNA1h2rYDNd^-4LcbyAA`tp{8=UP7(_1Svy{kV5Ggm(W6-7? zpRMbyjr15g!-)@{$YtdiFui%8dFp3g$#q=8$dLHBfSIdcjss>CdrpZvu3?S~n0dP1 zf;lc=$RVJ)aU3x5{J1W8MMsvrSTLWjWqD(vqLYb^#O8CbsmtGF zA)Fp`G(r3O2}MT6+9!l%7AOHHgk@e@dY4yuEL4M^z+959(FtvEB6~s@oM@a7WA|l9 zA>0$dH9OtqHKS#mei9fSe4)ZP2@DUu2qltnQd|Ed6b7a_|1PG7t6&QFx~Wm!&9?uBUY8o`SB`xV4U+(mYOS9yEzg z2_AuEOd@g_Xh0!PkOd`A3s6&mo))0X6zFLUdRlR}g)WsQbJmT_Sxx4w8=143 z%vo5X3A%x?S~R}TT5L2KI`aF{tb31#`IGl`j;{nR9r>M;A)WBPbVzp|MD397Jc!yM z-FaBe4(ZN=s2$Rs2T?nuI}frlpXE^3gAZXg$But&iLX(D5>uLOt{?0qFbtYGge0YXc~S3(Ob*!xNYeB}o4l>q2K zZz3ZA8Do7d0IUx%eJuc1!*Dbmzt#X>3xEj@bMk#2YE(2=-siPy%Yf+{Az+QN^*0dU z!P^?<>H9p^{NiU`xjp&qgeQIZZ$3 zJO55dd0k2QPDuF_uaYso6H+YOf2VA3p8LDZNUbxwS4q72wAMeojgfEm_=mUF@Ai}d z+EqY5$tW9uANBsl??s*a(bTmv>aLej_k*aTk9sn8K!r#@in_lfhUt93>nB;UP&pAV z{VW<-b&}Z4GU{&qtIiz#fRFvx!Qby_!wmN~Y5q~F?tsxv2jU^jW^W@yQD|hB`-O|9A>pgJk}K)OGD?fxOKg{^|Bbt8+3`*4Qp6kR>Mk8 zl*@X?T^2Kryh55lm$5L)q{C&m{p>Q zm)9h&fJBsDysm&mwAjC{fW%|MH6;>PKq5xfd*hQPpFuM1Bv<}T!X=D(RT)!8PFDq) zw-lMHAY<~kQ6j-t1sSs2RYAmBf39jGSKWwQ)kLns8lCu2MdYd?V!l?ws}7Wb*7v}D zWLT%F-wWI|YJz|7Ho?CKwvRT#_rPu`l>J^~lRNXhx!G{kaM2W{ks>3mYXI@#?xRaE=1^}4=yC%BY^31P6xj5~aUxR`j`KL<3Yf#XBgM*9K1R^10 zw(COEcNK~2Ao0l9tV`70R$O%*L>}qGmg}0xbxnjcy$&M2_%cBEj4w?ST6ci!Qtw0j zK>%-2P(J{88Q+Q$Y59ZJ{s#fNP1k!ce_`Gq09sxrDu4K&ptP`&vNHbr5tuE@@wp20 zM}XSF(2t^DX*~T1&~n@ghJJ*mPScM&8n|NlG2BX{_s4&aUNLxYC^Q)}-T>NS-dXL* zHv||y8!t4xp}}qlFe|{jL103|8_=+w4)AVJ|F+?=r4oHhRnqb&1uCP;p8)E^w<`^Q z0;mt)VczDBY8@M*AzAk)U{nwoKLJA~OG)jYfYC+=R6k)1`S6`W-_7hNbGOs6%|+V) znNxfNbi01f4q#y7Q9Zvs??%|!C103|Xvq3tU?7JWs% zd$Y{my@jzWn8@()mLT%JB615vmhd>$*|$KXx}G_=K*kQeZh?%9b8l%25Sd#bBXd`` zK*r8p-LlDK3iHTVmOgbyW|48`Z9(P(Mdr33vsYQ=wje`V-WEix*z2|?avMZs3`kS> zwpr}usFCuE0+4~`F9Kkn0{BG$6f1yVG{7$cz>2ee(Ez__vlGBC0>DMy1Zg0n$2$UG zzXG@;`t^VUxB~#04!HvWyI=35 zT><`~0>2Az4}M6OO7FaP1%bng*j-KFt{Z{7n!sH_;3GxgZfOGOOh5A}FNd#7MwGvT zga`jv!Tt&og*;IWs9%KztnL3-kg&ssUp0weH3>5FuY!a}8B^*vWqBDq{?=Upf1-eY z6TnB5hQDdk|0Y1KzWq&u{^kbyn^|1WQ6rH2IeZt0m`}m%4*-}IlkqJd^^&=#>x_E4 zCpmaea6_qh4~=?ou1g#xhb}qL(y2>Myyl@x9(c`DmpoDO(j_m}lY8ruH(o3Eq%M|Y zz4U3{Jd#chKn3k z`qmj45z@ECC2=1G{3k4e_6gZ1N8(VnL0pRif7_9y;?m6OD3`6sO0UndLxMAr^b z_1XG|ny#Q2vWu@(L_0sSRNY(t4=%wOo{enQ}1f%RgF|e;^`>N0|$K9ko1Z zUjD<(%UvART@Mr|8JRwSupyjceCnMC5H^HUFfL0Dyk*zo^Z){f=ppg|#u+Ml?g5PR zq|W3$fN`Eu_1^~h3DsJW>U1|h|5L?Sqr6e|IVWPVF^TnR`d@!D#^E72WSB0A3U zyh}hr&X5wfL0F;(VF^g2b9~{Im&)J-EW-VV{*E>k@McU;<$v1wmKLa@aeVJ3+PRX^qv9euKagJ!~paNy`~s|Pve~wyaD($ zF%b>GXXtIm0DPvZ_hwzV9~N#}^$kNsnC|ZZ!Q26WAv{58 z>HvUTJskjeQXeikpy^0Xp%rzS1I8Z8{{k9m>wvcXc^2<)zE=aAEKNvST4X%!6eO$@ zZKoh%ooG7+32Pa53L-NV5vL~N)I?|`I6*`%<4!>$NRe>5kw~ExfJn&0QV&7G`i!54 zAYq+oduU5|2m)3#;Gqe4XaZzv4>PEyqegpLP6$8-(w+jqI??tN0M?1Nrv~s80Bx35 zb;tv4Pa&!!twJP9M#)}6R9)1OrM-kG>*IZ1ZU*y$xHR*ns*V~)6?0=%M@UQI>X4_w z`>9}&Rx^?$P^&KgMGW>5`BjTSU2={6bHmJ_#ysN2ek+d@&I z{wN1ZDP}=6M~IeDPRQs;W0_>glTIHY!vkef%SXttKC$ORGW68*AuE}@x}&4HqlP0e zl-5*|BcsgnLXMY`Q(nmN=H|rej>pWfnvTF0wA@m283$Gn&C99g6-09%l!$r-vZnca zbw{*$wv{8$MT;`sDFZxT+?mAdVJRWPzPK})`zy!H7kA3N&lhCv>FKMdr?1=e^u?gf z=IN!9K-SwrY0)Q4#C#OY`vG*6K1A~a=xE*;O^AXYK!I2H)JM$jD$YK#;*#Dhv1kL1r>a)R6(ykwVJ= z5b3JZ904FA{igsBNzsd00Emp|lrSK>27t^EoRoXX)hxi=TH8?thbphObA$!b9{ME@ z5bJs{3j~QW;x^h;?YONH8rgAMB`~$)wn|`X$8D9s){fgMfvp|4RRUu>ZmR@#cHCA8 zj1jjD1uIgZ66|NkZIz7Daa$#$blg_SC>^&|GD^p7mGDIecHCB}sGzCiXJZ)o2K_N2 zWY|_2swMG?3b!&;OX7jLR61;{4AqkK@T?5gWY|_2YRRyT*3!ymuK|u4!^qhn5E+(L z5g=AR3l*lwSAZ~`3X*D3u#VhN2 z540ka)quDeyb9{6gKG%eyU2kh)5wsgrU0m_0BQ<=hDuOP&9|l-Kuz$Keo0LMP#t;@ zKuuWcNnXHb@@M%h@tCc4zFG=1IQC%@c-0c1)f8wg0oq8H$OWpdDAdwWwcK>6CC5>1 zC09DLwT0LkN>FVfwy_da8@kLDMyU;5MsdsbwE^&)swZPvy3`f`UC3c4V@a2_jsU2s z0PyXIuyYdyP)GMh9XEhF0GMt*3U*X8`wnnaO(AE3Buc-tu8>$uNvta*)>abhLZa-) zx{x@X*U|M>|JD^Yp|6c6^VeP42$@lGPe{IWJL?Jg^_2X2LVl2vQ%}pU=O(`%F%~AN z=O(`%bIB}yq7XIZFZ)mm;bp(2d4_TYtLmkohm}Nnzqh;fUpkbY(TJcVpsB@2Z z8kygQ!dZ3?ZkmXO?sc^F*@2ck7^Mx+3XH6S(dK2eqn*lXM{y9n8@EO2IxCEf5S8;_ zKDt3Rj4a(y)kTRq_i!`1jJlXI>ROf|&(*4o%GPDn37h=ueadai0BKi7UHdZXI!Fu` zU9`p>%V_wRsB@2BJBd2GKj|QiLI4_mGT;aj!>_&?enDdR1*_o~q=#RSfpnuizJv7m z3vwHOK{URH)mH#An5YkcWWE%2wBFSRz~kK1rPBLTeT;E?6RZymx!BhShFt7v4%Ii; z4hBfD0+9hlumD-6#0CqH<+@ZFBp4vc+)51vYmi_!kYEAgA|IYiB}0u6fF$t{WvUQ> zB=b;Zst}k;y0{@i3oGpt0sy&{hXBCNz=mKUmKoR(Y+32t`Yyi^I4An-Q+!U+T+qnj zt-jqc6b#aI3>*puX*vcD1%nY{O$Y^pG;YPfp4>CE6)wArjJ~YYY-ed@Jf`#xxcr`l@l( zSdX*Df`FApZLA42b|cVO6KE_5Y==~GjT&17bfP_lmUJQ^J-#L&VJD}XfP|f#ZlXyv z0SP3hl@*$35=}G-nzBt~x`p-!0+1eGQvj^e3G1c+SfvxzO#xs>xJ?1FN;}6*0U}+S zrT|%_6V^?ksmydVg{F4Gx+yfZ6V@rTArT4b3pNuZtb}zlkXX&FFD7dS5;9@k3tmG7G=XNC0BPCGywnx@B<*elAicxp0>H{wHy2u3`Re9EOX}n1LPKj&YOVpAYXBN# z&9#Qjg@#tXy1AvHov)_tlt{?5e7NY#Tc{(jaFAH9^VQ+HFT+J&S_@Y=NXP{(T=ylB z2-gED93<>~b@+bel2v500}#z837V+bL;!aB0$2aOvX=M9G^Obk0U}}y#@|4MRXTC}Z@W91av3OV=^uq`oGPLW(&YA(~E?L>1cr`S$3KZI9l zHEBovWrnx3a*E^t)15L2+8%d~;#Lx?J??yyhtgpM?rg7nx;@C+Nv!th7n#IrkAAU} zSnV;E?Ic!vjOSJ2;~q4g+haVZ;L{!%$vguO>*F5ec@r6#N$mhKn|PY)fes+EiH|^u z$aK(TI)Dsq6=wTZj)rDf4Tm2-ixtW`%Jdky=x2Fv+(pjTV~|*evqe6;?QC^IBiq^P z1X$bI>I7KZ+3Eyn+u7;_JJ`-vC)mPvwmQKUc6zK6Y*8vb)(OV2(_@|7oUKl7&Q>Qk zXRDK&v(?GX+3G~j)(=K``ei>=cj_co9suYgg2ZrH!% zQCJyE4JlZXo^&k6?HWErO_x}V+x2{~E|vDAV=->+urC(lR&M#R7_)ZnGgf4KhS6vs z5a}t$2@uO&j|0dW?XJgRa@e`gI5&_u4HD-D5+`$3G`t8zdcyGlv2&mC0C|HqR;y6F z0HF;nUI5Id@rwl^UIWCt0mO^krz=4LNKZIH09d)t1OTk#*1Lrh+_Xq=(;@*NGD1!O zh@B2i!1R{s&;(3vI~|%}IVIw&Z+drDB%~+Y86=Xpl@;wQNW2CckT#vQmYoFwD>K&_ z1Y}mUGZ8Qg9@AOTM2LG$XGIesZiCK>CPJLdiY7vwofS=lIGNQ-gg84Znkah3m8AGe zpEd~qYj}zpQAq$;!zsg0e3LZaBmgAqPuC~uUP;ouBHLTRcoGb@hSNK|XkSQz!SorS zcsEi`7ezw)v|WUjsft7wka&$hrATxE38_sNkg#(nU9^^6gqD;Wqyf}LZ&38#9J_#s zIWxpjd01D4C>_|YK(wwLH?Q0-~e6{vEobfvD+Nz|?~o06B?p@kKcJgz(Nakmb99JZ6$l*eH=JDc*jHR8z`7ul4QZi<9-R=a`3>wK6Z(G4VC zhYK!8Q8$o~36*XjVJB3&frN|&x`Bk9Q0XQUDzpoo;^`1cd;AjsC}WSOZOPu_d!UiM z$M*mWdynq{7WN+B15E5az6Y4tdwdVDvG@2MZhL$Wn5EPn-@|Q>@8Pz`_i)?ed${fK zJ>2&A9&USl50y}%-Ics1xefG$YVYz)W#FDr?OmRwOQpAgo?7G!@PN?*>rmB4BB5mhHLT(ei1c{LfwwEB0jS|iMUV5nY5(KP-N-s^Imm7gznm{i> zz)Gm}vIywVGll#IA|bbt-XLKoRCq`Uz3&5%O*)e40}vVg^#O>TQ0W6rWkRJ7G_?~deV}QngbH~- zL_%&OeFX_Cq0(27uo5bLK|&@}`U(P8LZz=J&{q>6E&IxZ3VBilAQLM61b~%L=_dfJ zgi1f5B`t;h1c0?J_0s_TGywH|KdoUup`n#f>1SzZCsfFFBNB4+=`Z@yN~rV)2|JUNJO=18@*a?*Z|0O}rDUp!-(Lj)}6Dk8i!cM3R1PME#G7v=U zgvvk=k&Ea+5U~>~13^S4R0e{`W9|x!43C_pHGH*rXFIg8{HfCs+mpz)r9X28cby z1_MM+vB3bb6D))E030j^pp{@53~fs#SjeR(5^~QPB1l*XmLY*$d{Bg3TnQ1fx$+4|>*n+p-+U1o4+oNcxGKZC zRQEdb?mlPb+am3Q=>JI7$`Gt;A8PXl^BrQfZi&b$eNfqcnA= zOdO@*PCIdwhCA)VQJNTFG}O}233lQr4I@}4j?yrK?Zim#L);%W`vkdNE|ioT{>};E)z%8Wv6(CSPX+%1|*i@R8k+> zPGu$<*-m99U~Q)|6R@^ZnF(mysmz2OY^O34wy>SbOxVIs9A&~5rJTx47{g8+Wx6?) znQl&Hrkhil>E={sx;d4Z>U~u-6z$x?NT~KM9}R0zH;#mA@A4d7D(zH`glcvWG!m-G z-ESn+vU3X~Wp07Sww+tZ5+Ii6nk7Ii&ovA7vvUhsZXj72B+CsXOXe16ve>zWY=GFg zg=~P>xrJ;2LKxuyYHe+_V_wro||L z$arxSKQ$7Dg))(kUDb5_WE3v>@>sra5UdT5CC45U_F! zqd`FC7Df{Rvv`2cE#yGl2Ax~TfjB$2kOOftw~zyIc5WdD;x>qbnjDC;a|=15S3<@p zzS6xLBaCLfWnl~e5M-NE20G+7HII=o^H_C{^v1@Dd#spwthmRDna8>rdMt?9??4!< z4Lw#Hns(-~GG@+IAky2)1<1R6j2h~>0I_4{Ty4l)VMxpG%msiP^tk}A-+_>eo|G|j zE_%|AnRBh4)G@OwPmz#bR-Pa+R*}d9i7h-ACF;#QO(G8@Y4}X42|I8f2NHJRJ`N;g;66@}uw1=yAR&FuaUfv_?&BzM zr?*WtV!O*TL2i~jS%a_?*S_&2_WRQ&j1 z(C^pL3-8KqF9;&xx-i z^g{{(DFrifj3eGG8tU-#D!})c*G_Vn_^0SA%pMDk(4rTgbS&hJui!&MGU-4(ukio* zDC#`ik?f83b5whL0^|R+{q8KsXU_67x;xmH_>R=u*#di2QRA_WpbmRLjE=WzaH0%+RSzw@il{X8?ARQcC_K<@a2wXX8J3R^9>{L(>x)U zm6QyJZI(I*;WuMJ_(q8M*a%1;+G~97$niyKOB}B{oaro_?OyKq-C6D|3|QiYUuOMR z9F@#~)sCCaEP8c~Yvd-~P-Lb*3+uPNa#j(~b8tPh_Uz_0IT<>e}KOgZrW(JsPi*tT>j0 z+U9t+M5!(QN@UTMSpuqCLs%<36Yx@7mQa+u)zQAXIed?^ZPC6Xjx*8SOI-9_E??lE zpQVf6oc-bK3WJd5|E^z%`bjMHKlSHPp9-h4=$i+Q5D)r<2`h4P=ODvH-x`~P;t)LP zE2@X$nT99T55sjho~f!l0@pEkX5g8L=SV!W@XW?@6rQ8;dAvY*a&psVr{)+h_RUKjVdMrSrRGe?sPIC<_}Glp{M59ZD)o95 zjL%5V7~#rEWuBdr)7hDR<0tyYCk~&ImpdWD@T(Znk7bO>%Sp}8=p2wSK6}#Az=Vkt zg7S06WIyv_=g!$|Oi;hUy%L9YX7N#tA|oQ21raxSfrY(yznFhB(|iAw1D8%7ukily zgFKEG?fT$+z_~AXe{T5s`rwX-XoP}{a%o`#pBen+p#ce0xWMa&LA z=yed8olbMg&29T)^+cZ|U0LnmpdW*S8a`e%vU}BozO!RIBR_LBi1SRGlARyqh;7l$ zGjVKsP;%zXPn3xhN8`oY@x&-ZJB>wCNq{9{f~c7vCLO1h;qn-TlnW$%o9 ze2dP;Yg-&w*+=j6otPGcMQco2ZhY>Ps9^;OS*c@3W;9wmySA@Ss@Gb_L65KvQVde_BPr*`ard*#u+sTB&nS*Wj1 z%fZ!JIO{v}hQ!5=oRl$;<&GbnmYX{|ob}Dh$jF}%o)D2cacn;C(Xvux_<^|e^yK`E zt>x-D3i2m3%5EG!Hg@5}NJrT4zOJBY9#`2ZkMRA67uV*6UgMm<8fWW;4X=Coj|$mA z&4VtdL>O_k>Kzfu9zlsWJfeT`2;2HaU;j_pk6#}8 z{Ow&APZfOd-o0ag9NwSoAN@(dLSV#)y8bkx!r%GZc+QAkV1)4<84K5?2Q?~e)HEov zw|BzcuBXqOKfB7;r)j5-F+tJeYX<$c&RF}|{n#@XPoDJk`Jz+DWbH>y?oAH*{!@R=Cxn9o{TpBd~ou&n`Pp~nmW7Fd&=3~bgHqH4)>)pGZ`G!Y2 zmg!UG(?w2~M;d%Kd!xN=t}b-=6nU?4R4|Gvzwi8!JF(x=&Rf|qD;GQ8HJ&Q^u-LiL z+qax^Ajaba8i@xV6=i+mOfk$;N1VsZ@yi{R@iskWEU9zzxK@eLEej%BC&aXgiJ#Ys z^`DS2e!|f1gV^Aqad~;2Q}bEs(C)b-Qgeo~epu9pCQcbKJR_$~cmx~qZ0qnT8B@}| z)0cFJ4K84pS$LxF%a>{f%qa-x!{Dl>-v$Fccnwcyyc3*bn zf#PU3t-!DI<54l6ux8%LCqIY`k2>_hXUk^#E*LsKH#dK%W1(?iX`jTT#Lmh6$_KY8 zs2KEGMXVlU@8plq%_(VlDdyS0zgza6QaggZG`x1+_qE%yh{(h?t=mSxnP?Li-8?2D znzd}+rgLN*wmer{Ku?~G*rN1ah;oGqG-?s}B5=I!3C8xqiHa4dZGj3*klZaLk* zW&fxB>EiNdu26jYM1$2+{qK3k`rmaG#Z12Jcg}d|8Cl|4;!mmqEzFs{1zUJ`xFa+Th(qFB}--Ck}33o36 zEy+WSFWPn5`HRs7eT(`;)U}2K7$Ib|5xygNjuGNM@*F#(RUBT820D3`BrgJgwFXK{ z*2et#tn;`3ztbq{oU>}hwxCH4a1>m{Nc=;eG;{DdXHvzee^sZNTd6wwKh<96o$V@; z_gq>?s@aFCTmGkd)p=)Z#a92RzD?Dw|5M%R0)({rPxT8IoI@7n4K-uFayB!MTyzGQ z3%_z!FgsktulZj&YkP0Rl0_?qS@4xJ!u{6hyh*SAGG!jz9Rk=tNy1xDS@H$&nNGFx!UH69}Wny>K9b|^1_!3LI(7heWBm9 zLwE1(wq7`LD&dcv&DST*cbe6H9QI)6COoRi497^+-?-`wH~N~@zjw9(sG0mdiW%k< zReTFY-fX0K;d|$6j@&7c=JadMU5@6BGuYRsbFcW0!EtTl;^RBVCt45GcS-0N91|bYwq;UM5(SL( ilay36@Rsu}qv+9X=V_;RyKce&j>3u_Ve5Z)dj3C_oik|w diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/bi/service/impl/SubpackagerelationServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/bi/service/impl/SubpackagerelationServiceImpl.java index 1ad4e7fa0..58af578f5 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/bi/service/impl/SubpackagerelationServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/bi/service/impl/SubpackagerelationServiceImpl.java @@ -250,6 +250,8 @@ public class SubpackagerelationServiceImpl implements SubpackagerelationService mp.put("子卷的物性值2", json.getString("un_plan_product_property2")); mp.put("子卷的物性值3", json.getString("un_plan_product_property3")); mp.put("木箱料号", json.getString("box_type")); + mp.put("内控标准抗拉下限", json.getString("standard_limit")); + mp.put("生产实际抗拉值", json.getString("actual_value")); mp.put("长", json.getString("box_length")); mp.put("宽", json.getString("box_width")); mp.put("高", json.getString("box_high")); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java index 29dba109f..a7645375e 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/RawAssistIStorServiceImpl.java @@ -74,18 +74,79 @@ public class RawAssistIStorServiceImpl implements RawAssistIStorService { map.put("bill_type", (String) whereJson.get("bill_type")); map.put("create_mode", (String) whereJson.get("create_mode")); map.put("bill_status", (String) whereJson.get("bill_status")); + String bill_code = MapUtil.getStr(whereJson, "bill_code"); String sap_pcsn = MapUtil.getStr(whereJson, "sap_pcsn"); String pcsn = MapUtil.getStr(whereJson, "pcsn"); + String box_no = MapUtil.getStr(whereJson, "box_no"); + String vbeln = MapUtil.getStr(whereJson, "vbeln"); + + if (!ObjectUtil.isEmpty(bill_code)) { map.put("bill_code", "%" + bill_code + "%"); } - if (!ObjectUtil.isEmpty(sap_pcsn)) { - map.put("sap_pcsn", "%" + sap_pcsn + "%"); + + // 空格查询 + if (StrUtil.isNotEmpty(pcsn)) { + // 判断是否有空格 + boolean matches = pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = pcsn.split(" "); + String pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("pcsn_in", "('"+pcsn_in+"')"); + } else { + map.put("pcsn", "%" + pcsn + "%"); + } } - if (!ObjectUtil.isEmpty(pcsn)) { - map.put("pcsn", "%" + pcsn + "%"); + + // 空格查询 + if (StrUtil.isNotEmpty(sap_pcsn)) { + // 判断是否有空格 + boolean matches = sap_pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = sap_pcsn.split(" "); + String sap_pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("sap_pcsn_in", "('"+sap_pcsn_in+"')"); + } else { + map.put("sap_pcsn", "%" + sap_pcsn + "%"); + } } + + // 空格查询 + if (StrUtil.isNotEmpty(box_no)) { + // 判断是否有空格 + boolean matches = box_no.matches(".*\\s.*"); + + if (matches) { + String[] s = box_no.split(" "); + String box_no_in = String.join("','", Arrays.asList(s)); + + map.put("box_no_in", "('"+box_no_in+"')"); + } else { + map.put("box_no", "%" + box_no + "%"); + + } + } + + // 空格查询 + if (StrUtil.isNotEmpty(vbeln)) { + // 判断是否有空格 + boolean matches = vbeln.matches(".*\\s.*"); + + if (matches) { + String[] s = vbeln.split(" "); + String vbeln_in = String.join("','", Arrays.asList(s)); + + map.put("vbeln_in", "('"+vbeln_in+"')"); + } else { + map.put("vbeln", "%" + vbeln + "%"); + } + } + String begin_time = (String) whereJson.get("begin_time"); if (!StrUtil.isEmpty(begin_time)) { diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/StorPublicServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/StorPublicServiceImpl.java index 0b7cb5dd3..05306e8fe 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/StorPublicServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/service/impl/StorPublicServiceImpl.java @@ -449,6 +449,7 @@ public class StorPublicServiceImpl implements StorPublicService { String lock_type = from.getString("lock_type"); //载具编码 String storagevehicle_code = from.getString("storagevehicle_code"); + String is_overdue = from.getString("is_overdue"); if (StrUtil.isEmpty(struct_id) && StrUtil.isEmpty(point_code)) { throw new BadRequestException("点位仓位更新出入参数异常!"); } @@ -479,6 +480,10 @@ public class StorPublicServiceImpl implements StorPublicService { map.put("vehicle_code", storagevehicle_code); map.put("point_status", "01"); } + if ("1".equals(from.getString("is_overdue")) && StrUtil.isNotEmpty(is_overdue)) { + map.put("storagevehicle_code", storagevehicle_code); + } + wo_Struct.update(map, "struct_id = '" + jo.getString("struct_id") + "'"); wo_Point.update(map, "point_id = '" + jo.getString("point_id") + "'"); } else {//锁定 diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql index 9fec70b16..9249da216 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/inbill/wql/QST_IVT_RAWASSISTISTOR.wql @@ -41,6 +41,11 @@ 输入.in_stor_id TYPEAS f_string 输入.in_layer_num TYPEAS f_string 输入.box_height TYPEAS s_string + 输入.vbeln TYPEAS s_string + 输入.pcsn_in TYPEAS f_string + 输入.sap_pcsn_in TYPEAS f_string + 输入.vbeln_in TYPEAS f_string + 输入.box_no_in TYPEAS f_string [临时表] @@ -68,10 +73,12 @@ IF 输入.flag = "1" PAGEQUERY SELECT DISTINCT - ios.* + ios.*, + IFNULL(dtl.vbeln,'') as vbeln FROM ST_IVT_IOStorInv ios - LEFT JOIN st_ivt_iostorinvdis dis ON dis.iostorinv_id = ios.iostorinv_id + LEFT JOIN st_ivt_iostorinvdtl dtl ON ios.iostorinv_id = dtl.iostorinv_id + LEFT JOIN st_ivt_iostorinvdis dis ON dtl.iostorinvdtl_id = dis.iostorinvdtl_id LEFT JOIN pdm_bi_subpackagerelation sub ON sub.container_name = dis.pcsn WHERE ios.is_delete = '0' @@ -79,30 +86,62 @@ ios.io_type = '0' AND ios.stor_id in 输入.in_stor_id + OPTION 输入.box_no <> "" + dis.box_no like 输入.box_no + ENDOPTION + + OPTION 输入.box_no_in <> "" + dis.box_no IN 输入.box_no_in + ENDOPTION + + OPTION 输入.vbeln <> "" + dtl.vbeln like 输入.vbeln + ENDOPTION + + OPTION 输入.vbeln_in <> "" + dtl.vbeln IN 输入.vbeln_in + ENDOPTION + OPTION 输入.bill_code <> "" ios.bill_code like 输入.bill_code ENDOPTION + OPTION 输入.sap_pcsn <> "" sub.sap_pcsn like 输入.sap_pcsn ENDOPTION + + OPTION 输入.sap_pcsn_in <> "" + sub.sap_pcsn IN 输入.sap_pcsn_in + ENDOPTION + OPTION 输入.pcsn <> "" dis.pcsn like 输入.pcsn ENDOPTION + + OPTION 输入.pcsn_in <> "" + dis.pcsn IN 输入.pcsn_in + ENDOPTION + OPTION 输入.stor_id <> "" ios.stor_id = 输入.stor_id ENDOPTION + OPTION 输入.bill_type <> "" ios.bill_type = 输入.bill_type ENDOPTION + OPTION 输入.create_mode <> "" ios.create_mode = 输入.create_mode ENDOPTION + OPTION 输入.bill_status <> "" ios.bill_status = 输入.bill_status ENDOPTION + OPTION 输入.begin_time <> "" ios.input_time >= 输入.begin_time ENDOPTION + OPTION 输入.end_time <> "" ios.input_time <= 输入.end_time ENDOPTION diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/rest/ProductScrapController.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/rest/ProductScrapController.java index 130c00959..624e7af18 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/rest/ProductScrapController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/rest/ProductScrapController.java @@ -1,5 +1,6 @@ package org.nl.wms.st.instor.rest; +import cn.dev33.satoken.annotation.SaIgnore; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -9,7 +10,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; import java.util.Map; @RestController @@ -82,4 +85,10 @@ public class ProductScrapController { return new ResponseEntity<>(HttpStatus.CREATED); } + @PostMapping("/importExcel") + @SaIgnore + public ResponseEntity importExcel(@RequestParam("file") MultipartFile file, HttpServletRequest request) { + return new ResponseEntity<>(productScrapService.importExcel(file, request),HttpStatus.OK); + } + } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/ProductScrapService.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/ProductScrapService.java index d3a75744a..06937faec 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/ProductScrapService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/ProductScrapService.java @@ -3,7 +3,10 @@ package org.nl.wms.st.instor.service; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; import java.util.Map; public interface ProductScrapService { @@ -65,4 +68,12 @@ public interface ProductScrapService { * @param whereJson / */ void onSubmit(JSONObject whereJson); + + /** + * 导入excel + * @param file : 文件 + * @param request post请求 + * @return + */ + ArrayList importExcel(MultipartFile file, HttpServletRequest request); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java index 3ce225550..39d0373ae 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/HandMoveStorServiceImpl.java @@ -830,15 +830,62 @@ public class HandMoveStorServiceImpl implements HandMoveStorService { if (StrUtil.isNotEmpty(map.get("struct_code"))) { map.put("struct_code", "%" + map.get("struct_code") + "%"); } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("pcsn"))) { - map.put("pcsn", "%" + map.get("pcsn") + "%"); + // 判断是否有空格 + String pcsn = MapUtil.getStr(map, "pcsn"); + + boolean matches = pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = pcsn.split(" "); + String pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("pcsn_in", "('"+pcsn_in+"')"); + map.put("pcsn", ""); + } else { + map.put("pcsn", "%" + map.get("pcsn") + "%"); + } } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("sap_pcsn"))) { - map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + // 判断是否有空格 + String sap_pcsn = MapUtil.getStr(map, "sap_pcsn"); + + boolean matches = sap_pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = sap_pcsn.split(" "); + String sap_pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("sap_pcsn_in", "('"+sap_pcsn_in+"')"); + map.put("sap_pcsn", ""); + } else { + map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + } } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("package_box_sn"))) { - map.put("package_box_sn", "%" + map.get("package_box_sn") + "%"); + // 判断是否有空格 + String package_box_sn = MapUtil.getStr(map, "package_box_sn"); + + boolean matches = package_box_sn.matches(".*\\s.*"); + + if (matches) { + String[] s = package_box_sn.split(" "); + String box_no_in = String.join("','", Arrays.asList(s)); + + map.put("package_box_sn_in", "('"+box_no_in+"')"); + map.put("package_box_sn", ""); + } else { + map.put("package_box_sn", "%" + map.get("package_box_sn") + "%"); + + } } + if (StrUtil.isNotEmpty(map.get("sale_order_name"))) { map.put("sale_order_name", "%" + map.get("sale_order_name") + "%"); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/ProductScrapServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/ProductScrapServiceImpl.java index bf026fe00..9d1f70e4a 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/ProductScrapServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/service/impl/ProductScrapServiceImpl.java @@ -6,6 +6,8 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.poi.excel.ExcelReader; +import cn.hutool.poi.excel.ExcelUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -28,7 +30,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; +import java.io.InputStream; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -448,4 +454,69 @@ public class ProductScrapServiceImpl implements ProductScrapService { } + @Override + @Transactional(rollbackFor = Exception.class) + public ArrayList importExcel(MultipartFile file, HttpServletRequest request) { + // 1.获取上传文件输入流 + InputStream inputStream = null; + + try { + inputStream = file.getInputStream(); + } catch (Exception e) { + e.printStackTrace(); + } + + ExcelReader excelReader = ExcelUtil.getReader(inputStream); + List> read = excelReader.read(1, excelReader.getRowCount()); + + // 获取此仓库的所有库存 + String stor_id = request.getParameter("stor_id"); + + UserStorServiceImpl userStorService = new UserStorServiceImpl(); + String in_stor_id = userStorService.getInStor(); + + List ivtList = WQL.getWO("QST_IVT_HANDMOVESTOR") + .addParam("flag", "3").addParam("stor_id", stor_id).addParam("in_stor_id",in_stor_id) + .process().getResultJSONArray(0).toJavaList(JSONObject.class); + + // 循环获取的数据 + ArrayList resultList = new ArrayList<>(); + for (int i = 0; i < read.size(); i++) { + List list = read.get(i); + + // pcsn + String pcsn = list.get(0).toString(); + // sap批次号 + String sap_pcsn = list.get(1).toString(); + // 木箱号 + String box_no = list.get(2).toString(); + // 重量 + String qty = list.get(3).toString(); + + // 子卷号和批次号必须有一个不为空 + if (ObjectUtil.isEmpty(pcsn) && ObjectUtil.isEmpty(sap_pcsn)) { + continue; + } + + // 匹配库存 + List oneList = ivtList.stream() + .filter(row -> row.getString("pcsn").equals(pcsn) || + row.getString("sap_pcsn").equals(sap_pcsn) + ) + .collect(Collectors.toList()); + + if (ObjectUtil.isNotEmpty(oneList)) { + JSONObject json = oneList.get(0); + + // 匹配相同箱号的数据 + List boxList = ivtList.stream() + .filter(row -> row.getString("storagevehicle_code").equals(json.getString("storagevehicle_code"))) + .collect(Collectors.toList()); + + resultList.addAll(boxList); + } + } + return resultList; + } + } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/wql/QST_IVT_HANDMOVESTOR.wql b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/wql/QST_IVT_HANDMOVESTOR.wql index 02d7e3f4c..d51b2c4e8 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/wql/QST_IVT_HANDMOVESTOR.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/instor/wql/QST_IVT_HANDMOVESTOR.wql @@ -42,11 +42,14 @@ 输入.storagevehicle_code TYPEAS s_string 输入.struct_code TYPEAS s_string 输入.block_num TYPEAS s_string - 输入.row_num TYPEAS s_string - 输入.out_order_seq TYPEAS s_string - 输入.ids TYPEAS f_string - 输入.deptIds TYPEAS f_string + 输入.row_num TYPEAS s_string + 输入.out_order_seq TYPEAS s_string + 输入.ids TYPEAS f_string + 输入.deptIds TYPEAS f_string 输入.in_stor_id TYPEAS f_string + 输入.package_box_sn_in TYPEAS f_string + 输入.sap_pcsn_in TYPEAS f_string + 输入.pcsn_in TYPEAS f_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -188,33 +191,55 @@ OPTION 输入.material_id <> "" ivt2.material_id = 输入.material_id ENDOPTION + OPTION 输入.remark <> "" (mb.material_code like 输入.remark or mb.material_name like 输入.remark) ENDOPTION + OPTION 输入.ids <> "" struct.storagevehicle_code in (输入.ids) ENDOPTION + OPTION 输入.struct_code <> "" struct.struct_code like 输入.struct_code ENDOPTION + OPTION 输入.stor_id <> "" struct.stor_id = 输入.stor_id ENDOPTION + OPTION 输入.sect_id <> "" struct.sect_id = 输入.sect_id ENDOPTION + OPTION 输入.pcsn <> "" ivt2.pcsn like 输入.pcsn ENDOPTION + + OPTION 输入.pcsn_in <> "" + ivt2.pcsn IN 输入.pcsn_in + ENDOPTION + OPTION 输入.sap_pcsn <> "" sub.sap_pcsn like 输入.sap_pcsn ENDOPTION + + OPTION 输入.sap_pcsn_in <> "" + sub.sap_pcsn IN 输入.sap_pcsn_in + ENDOPTION + OPTION 输入.package_box_sn <> "" sub.package_box_sn like 输入.package_box_sn ENDOPTION + + OPTION 输入.package_box_sn_in <> "" + sub.package_box_sn IN 输入.package_box_sn_in + ENDOPTION + OPTION 输入.sale_order_name <> "" sub.sale_order_name like 输入.sale_order_name ENDOPTION + ENDSELECT ENDPAGEQUERY ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java index 01e57b178..35440c6c6 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/service/impl/CheckOutBillServiceImpl.java @@ -33,6 +33,7 @@ import org.nl.wms.st.inbill.service.StorPublicService; import org.nl.wms.st.instor.service.HandMoveStorService; import org.nl.wms.st.instor.service.impl.HandMoveStorServiceImpl; import org.nl.wms.st.instor.task.HandMoveStorAcsTask; +import org.nl.wms.st.returns.service.InAndOutReturnService; import org.nl.wms.st.returns.service.impl.InAndOutRetrunServiceImpl; import org.nl.wms.util.TranUtil; import org.springframework.data.domain.Pageable; @@ -44,6 +45,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; import java.util.function.Consumer; +import java.util.stream.Collectors; /** * PC端出入库新增 @@ -58,6 +60,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { private final HandMoveStorService handMoveStorService; private final OutTask outTask; private final HandMoveStorAcsTask moveStorAcsTask; + private final InAndOutReturnService inAndOutReturnService; @Override public Map pageQuery(Map whereJson, Pageable page, String[] stor_id, String[] bill_status, String[] bill_type) { @@ -76,24 +79,87 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { if (StrUtil.isNotEmpty(map.get("is_upload"))) { map.put("is_upload", map.get("is_upload")); } - if (StrUtil.isNotEmpty(map.get("pcsn"))) { - map.put("pcsn", "%" + map.get("pcsn") + "%"); - } if (StrUtil.isNotEmpty(map.get("material_code"))) { map.put("material_code", "%" + map.get("material_code") + "%"); } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("vbeln"))) { - map.put("vbeln", "%" + map.get("vbeln") + "%"); + // 判断是否有空格 + String vbeln = MapUtil.getStr(map, "vbeln"); + + boolean matches = vbeln.matches(".*\\s.*"); + + if (matches) { + String[] s = vbeln.split(" "); + String vbeln_in = String.join("','", Arrays.asList(s)); + + map.put("vbeln_in", "('"+vbeln_in+"')"); + map.put("vbeln", ""); + } else { + map.put("vbeln", "%" + map.get("vbeln") + "%"); + } } + + // 空格查询 + if (StrUtil.isNotEmpty(map.get("box_no"))) { + // 判断是否有空格 + String box_no = MapUtil.getStr(map, "box_no"); + + boolean matches = box_no.matches(".*\\s.*"); + + if (matches) { + String[] s = box_no.split(" "); + String box_no_in = String.join("','", Arrays.asList(s)); + + map.put("box_no_in", "('"+box_no_in+"')"); + map.put("box_no", ""); + } else { + map.put("box_no", "%" + map.get("box_no") + "%"); + + } + } + if (StrUtil.isNotEmpty(map.get("width"))) { map.put("width", "%" + map.get("width") + "%"); } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("pcsn"))) { - map.put("pcsn", "%" + map.get("pcsn") + "%"); + // 判断是否有空格 + String pcsn = MapUtil.getStr(map, "pcsn"); + + boolean matches = pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = pcsn.split(" "); + String pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("pcsn_in", "('"+pcsn_in+"')"); + map.put("pcsn", ""); + } else { + map.put("pcsn", "%" + map.get("pcsn") + "%"); + } } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("sap_pcsn"))) { - map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + // 判断是否有空格 + String sap_pcsn = MapUtil.getStr(map, "sap_pcsn"); + + boolean matches = sap_pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = sap_pcsn.split(" "); + String sap_pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("sap_pcsn_in", "('"+sap_pcsn_in+"')"); + map.put("sap_pcsn", ""); + } else { + map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + } } + if (StrUtil.isNotEmpty(map.get("cust_code"))) { map.put("cust_code", "%" + map.get("cust_code") + "%"); } @@ -151,23 +217,65 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { map.put("flag", "7"); map.put("begin_time", MapUtil.getStr(whereJson, "begin_time")); map.put("end_time", MapUtil.getStr(whereJson, "end_time")); - map.put("sap_pcsn", MapUtil.getStr(whereJson, "sap_pcsn")); map.put("stor_id", MapUtil.getStr(whereJson, "stor_id")); - map.put("package_box_sn", MapUtil.getStr(whereJson, "package_box_sn")); map.put("canuse_qty", "0"); if (StrUtil.isNotEmpty(map.get("material_code"))) { map.put("material_code", "%" + map.get("material_code") + "%"); } - if (StrUtil.isNotEmpty(map.get("pcsn"))) { - map.put("pcsn", "%" + map.get("pcsn") + "%"); + + // 空格查询 + String pcsn = MapUtil.getStr(whereJson, "pcsn"); + if (StrUtil.isNotEmpty(pcsn)) { + // 判断是否有空格 + boolean matches = pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = pcsn.split(" "); + String pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("pcsn_in", "('"+pcsn_in+"')"); + map.put("pcsn", ""); + } else { + map.put("pcsn", "%" + pcsn + "%"); + } } - if (StrUtil.isNotEmpty(map.get("sap_pcsn"))) { - map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + + // 空格查询 + String sap_pcsn = MapUtil.getStr(whereJson, "sap_pcsn"); + if (StrUtil.isNotEmpty(sap_pcsn)) { + // 判断是否有空格 + boolean matches = sap_pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = sap_pcsn.split(" "); + String sap_pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("sap_pcsn_in", "('"+sap_pcsn_in+"')"); + map.put("sap_pcsn", ""); + } else { + map.put("sap_pcsn", "%" + sap_pcsn + "%"); + } } - if (StrUtil.isNotEmpty(map.get("package_box_sn"))) { - map.put("package_box_sn", "%" + map.get("package_box_sn") + "%"); + + // 空格查询 + String package_box_sn = MapUtil.getStr(whereJson, "package_box_sn"); + if (StrUtil.isNotEmpty(package_box_sn)) { + // 判断是否有空格 + boolean matches = package_box_sn.matches(".*\\s.*"); + + if (matches) { + String[] s = package_box_sn.split(" "); + String package_box_sn_in = String.join("','", Arrays.asList(s)); + + map.put("box_no_in", "('"+package_box_sn_in+"')"); + map.put("box_no", ""); + } else { + map.put("box_no", "%" + map.get("package_box_sn") + "%"); + + } } + if (StrUtil.isNotEmpty(map.get("width_standard"))) { map.put("width_standard", map.get("width_standard")); } @@ -733,24 +841,87 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { if (StrUtil.isNotEmpty(map.get("is_upload"))) { map.put("is_upload", map.get("is_upload")); } - if (StrUtil.isNotEmpty(map.get("pcsn"))) { - map.put("pcsn", "%" + map.get("pcsn") + "%"); - } if (StrUtil.isNotEmpty(map.get("material_code"))) { map.put("material_code", "%" + map.get("material_code") + "%"); } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("vbeln"))) { - map.put("vbeln", "%" + map.get("vbeln") + "%"); + // 判断是否有空格 + String vbeln = MapUtil.getStr(map, "vbeln"); + + boolean matches = vbeln.matches(".*\\s.*"); + + if (matches) { + String[] s = vbeln.split(" "); + String vbeln_in = String.join("','", Arrays.asList(s)); + + map.put("vbeln_in", "('"+vbeln_in+"')"); + map.put("vbeln", ""); + } else { + map.put("vbeln", "%" + map.get("vbeln") + "%"); + } } + + // 空格查询 + if (StrUtil.isNotEmpty(map.get("box_no"))) { + // 判断是否有空格 + String box_no = MapUtil.getStr(map, "box_no"); + + boolean matches = box_no.matches(".*\\s.*"); + + if (matches) { + String[] s = box_no.split(" "); + String box_no_in = String.join("','", Arrays.asList(s)); + + map.put("box_no_in", "('"+box_no_in+"')"); + map.put("box_no", ""); + } else { + map.put("box_no", "%" + map.get("box_no") + "%"); + + } + } + if (StrUtil.isNotEmpty(map.get("width"))) { map.put("width", "%" + map.get("width") + "%"); } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("pcsn"))) { - map.put("pcsn", "%" + map.get("pcsn") + "%"); + // 判断是否有空格 + String pcsn = MapUtil.getStr(map, "pcsn"); + + boolean matches = pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = pcsn.split(" "); + String pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("pcsn_in", "('"+pcsn_in+"')"); + map.put("pcsn", ""); + } else { + map.put("pcsn", "%" + map.get("pcsn") + "%"); + } } + + // 空格查询 if (StrUtil.isNotEmpty(map.get("sap_pcsn"))) { - map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + // 判断是否有空格 + String sap_pcsn = MapUtil.getStr(map, "sap_pcsn"); + + boolean matches = sap_pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = sap_pcsn.split(" "); + String sap_pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("sap_pcsn_in", "('"+sap_pcsn_in+"')"); + map.put("sap_pcsn", ""); + } else { + map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + } } + if (StrUtil.isNotEmpty(map.get("cust_code"))) { map.put("cust_code", "%" + map.get("cust_code") + "%"); } @@ -1108,6 +1279,9 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { dtl.put("is_issued", "0"); dtl.put("plan_qty", ivt2.getDoubleValue("change_qty")); dtl.put("real_qty", ivt2.getDoubleValue("change_qty")); + dtl.put("is_overdue", ivt2.getString("is_overdue")); + dtl.put("instorage_time", ivt2.getString("instorage_time")); + // 如果所属仓位是虚拟区 则将分配明细状态变为生成 JSONObject jsonSect = wo_sect.query("sect_id = '" + ivt2.getString("sect_id") + "'").uniqueResult(0); if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { @@ -1115,6 +1289,12 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { } else { dtl.put("work_status", "00"); } + + // 判断是否超期 + if (ivt2.getString("is_overdue").equals("1")) { + dtl.put("work_status", "01"); + } + wo_dis.insert(dtl); } //记录需锁定的仓位 @@ -1167,6 +1347,8 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { dtl.put("is_issued", "0"); dtl.put("plan_qty", jsonIvt.getDoubleValue("change_qty")); dtl.put("real_qty", jsonIvt.getDoubleValue("change_qty")); + dtl.put("is_overdue", jsonIvt.getString("is_overdue")); + dtl.put("instorage_time", jsonIvt.getString("instorage_time")); // 如果所属仓位是虚拟区 则将分配明细状态变为生成 JSONObject jsonSect = wo_sect.query("sect_id = '" + jsonIvt.getString("sect_id") + "'").uniqueResult(0); if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { @@ -1174,6 +1356,11 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { } else { dtl.put("work_status", "00"); } + + // 判断是否超期 + if (jsonIvt.getString("is_overdue").equals("1")) { + dtl.put("work_status", "01"); + } wo_dis.insert(dtl); //记录需锁定的仓位 (如果此明细有相同物料的且子卷号不能为空的则在最后一个明细分配完成后锁定仓位) @@ -1347,6 +1534,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { dtl.put("is_issued", "0"); dtl.put("plan_qty", ivt2.getDoubleValue("change_qty")); dtl.put("real_qty", ivt2.getDoubleValue("change_qty")); + dtl.put("instorage_time", ivt2.getString("instorage_time")); // 如果所属仓位是虚拟区 则将分配明细状态变为生成 JSONObject jsonSect = wo_sect.query("sect_id = '" + ivt2.getString("sect_id") + "'").uniqueResult(0); if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { @@ -1406,6 +1594,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { dtl.put("is_issued", "0"); dtl.put("plan_qty", jsonIvt.getDoubleValue("change_qty")); dtl.put("real_qty", jsonIvt.getDoubleValue("change_qty")); + dtl.put("instorage_time", jsonIvt.getString("instorage_time")); // 如果所属仓位是虚拟区 则将分配明细状态变为生成 JSONObject jsonSect = wo_sect.query("sect_id = '" + jsonIvt.getString("sect_id") + "'").uniqueResult(0); if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { @@ -4195,6 +4384,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { dtl.put("is_issued", "0"); dtl.put("plan_qty", ivt.getDoubleValue("change_qty")); dtl.put("real_qty", ivt.getDoubleValue("change_qty")); + dtl.put("instorage_time", ivt.getString("instorage_time")); // 如果所属仓位是虚拟区 则将分配明细状态变为生成 JSONObject jsonSect = wo_sect.query("sect_id = '" + ivt.getString("sect_id") + "'").uniqueResult(0); if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { @@ -4263,6 +4453,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { json.put("is_issued", "0"); json.put("plan_qty", ivt.getDoubleValue("change_qty")); json.put("real_qty", ivt.getDoubleValue("change_qty")); + json.put("instorage_time", ivt.getString("instorage_time")); // 如果所属仓位是虚拟区 则将分配明细状态变为生成 JSONObject jsonSect = wo_sect.query("sect_id = '" + ivt.getString("sect_id") + "'").uniqueResult(0); if (StrUtil.equals(jsonSect.getString("sect_type_attr"), "09")) { @@ -4393,15 +4584,29 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { dis.put("inv_id", iostorinv_id); dis.put("bill_code", jo_mst.getString("bill_code")); dis.put("bill_table", "ST_IVT_IOStorInv"); - storPublicService.IOStor(dis, "21"); + + if (dis.getString("is_overdue").equals("1")) { + storPublicService.IOStor(dis, "12"); + } else { + storPublicService.IOStor(dis, "21"); + } } //解锁起点 JSONObject from_start = new JSONObject(); from_start.put("struct_id", dis.getString("struct_id")); from_start.put("lock_type", "1"); - from_start.put("storagevehicle_code", ""); + from_start.put("is_overdue", dis.getString("is_overdue")); + if (dis.getString("is_overdue").equals("1")) { + from_start.put("storagevehicle_code", dis.getString("box_no")); + } else { + from_start.put("storagevehicle_code", ""); + } storPublicService.updateStructAndPoint(from_start); + if (dis.getString("is_overdue").equals("1")) { + continue; + } + //查询对应明细 JSONObject dtl_jo = WQLObject.getWQLObject("st_ivt_iostorinvdtl").query("iostorinvdtl_id = '" + dis.getString("iostorinvdtl_id") + "'").uniqueResult(0); // 更新子卷包装关系表 状态 - 3 @@ -4459,7 +4664,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { } JSONObject mst_row = mst_wql.query("iostorinv_id = '" + iostorinv_id + "'").uniqueResult(0); - JSONArray dis_rows = dis_wql.query("iostorinv_id = '" + iostorinv_id + "'").getResultJSONArray(0); + JSONArray dis_rows = dis_wql.query("iostorinv_id = '" + iostorinv_id + "' and is_overdue = '0'").getResultJSONArray(0); //生成手工入库单 String new_iostorinv_id = IdUtil.getSnowflake(1, 1).nextId() + ""; @@ -4485,8 +4690,8 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { jo_mst.put("update_optname", nickName); jo_mst.put("update_time", now); jo_mst.put("out_stor_id", out_jo.getString("stor_id")); - mst_wql.insert(jo_mst); + double total_qty = 0.00; for (int i = 0; i < dis_rows.size(); i++) { //插入明细表 String iostorinvdtl_id = IdUtil.getSnowflake(1, 1).nextId() + ""; @@ -4523,11 +4728,26 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { //插入分配表 dis_wql.insert(dis_row); + total_qty = NumberUtil.add(total_qty,dis_row.getDoubleValue("plan_qty")); + //将包装关系中对应的记录状态改为包装 HashMap map = new HashMap<>(); map.put("status", "1"); WQLObject.getWQLObject("PDM_BI_SubPackageRelation").update(map, "package_box_SN = '" + dis_row.getString("box_no") + "' AND status = '3'"); } + + // 查询所有明细并计算实际重量 + List dtlList = dtl_wql.query("iostorinv_id = '" + iostorinv_id + "'") + .getResultJSONArray(0).toJavaList(JSONObject.class); + + double assign_qty = dtlList.stream() + .map(row -> row.getDoubleValue("assign_qty")) + .reduce(Double::sum).orElse(0.00); + + jo_mst.put("detail_count", dis_rows.size()); + // jo_mst.put("total_qty", total_qty); + jo_mst.put("total_qty", assign_qty); + mst_wql.insert(jo_mst); } /*if (out_jo.getString("bill_type").equals("1003")) { @@ -4547,7 +4767,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { if ("1003".equals(out_jo.getString("bill_type")) || "1006".equals(out_jo.getString("bill_type"))) { //如果为返检出库或者改切出库删除对应的包装关系 - JSONArray dis_rows = WQLObject.getWQLObject("ST_IVT_IOStorInvDis").query("iostorinv_id = '" + iostorinv_id + "'").getResultJSONArray(0); + JSONArray dis_rows = WQLObject.getWQLObject("ST_IVT_IOStorInvDis").query("iostorinv_id = '" + iostorinv_id + "' and is_overdue = '0'").getResultJSONArray(0); for (int i = 0; i < dis_rows.size(); i++) { JSONObject dis_row = dis_rows.getJSONObject(i); String sect_code = dis_row.getString("sect_code"); @@ -5106,6 +5326,15 @@ public class CheckOutBillServiceImpl implements CheckOutBillService { WQLObject mstTab = WQLObject.getWQLObject("ST_IVT_IOStorInv"); mstTab.update(whereJson); + // 回传sap + JSONObject jsonMst = mstTab.query("iostorinv_id = '" + whereJson.getString("iostorinv_id") + "'").uniqueResult(0); + + JSONArray jsonArr = new JSONArray(); + jsonArr.add(jsonMst); + + JSONObject param = new JSONObject(); + param.put("rows", jsonArr); + inAndOutReturnService.uploadSAP(param); } @Override diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/QST_IVT_CHECKOUTBILL.wql b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/QST_IVT_CHECKOUTBILL.wql index 68ee63ede..9f3c310f5 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/QST_IVT_CHECKOUTBILL.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/QST_IVT_CHECKOUTBILL.wql @@ -61,6 +61,10 @@ 输入.storIds TYPEAS f_string 输入.billStatuses TYPEAS f_string 输入.billTypes TYPEAS f_string + 输入.pcsn_in TYPEAS f_string + 输入.sap_pcsn_in TYPEAS f_string + 输入.vbeln_in TYPEAS f_string + 输入.box_no_in TYPEAS f_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -125,6 +129,10 @@ sub.sap_pcsn like 输入.sap_pcsn ENDOPTION + OPTION 输入.sap_pcsn_in <> "" + sub.sap_pcsn IN 输入.sap_pcsn_in + ENDOPTION + OPTION 输入.cust_code <> "" (cu.cust_code like 输入.cust_code or cu.cust_simple_name like 输入.cust_code) @@ -134,6 +142,10 @@ dis.pcsn like 输入.pcsn ENDOPTION + OPTION 输入.pcsn_in <> "" + dis.pcsn IN 输入.pcsn_in + ENDOPTION + OPTION 输入.is_upload <> "" ios.is_upload = 输入.is_upload ENDOPTION @@ -146,10 +158,22 @@ dtl.vbeln like 输入.vbeln ENDOPTION - OPTION 输入.width <> "" + OPTION 输入.vbeln_in <> "" + dtl.vbeln IN 输入.vbeln_in + ENDOPTION + + OPTION 输入.width <> "" dtl.width like 输入.width ENDOPTION + OPTION 输入.box_no <> "" + dis.box_no like 输入.box_no + ENDOPTION + + OPTION 输入.box_no_in <> "" + dis.box_no IN 输入.box_no_in + ENDOPTION + OPTION 输入.billTypes <> "" ios.bill_type in 输入.billTypes ENDOPTION @@ -222,6 +246,24 @@ sub.sap_pcsn like 输入.sap_pcsn ENDOPTION + OPTION 输入.sap_pcsn_in <> "" + sub.sap_pcsn IN 输入.sap_pcsn_in + ENDOPTION + + OPTION 输入.pcsn_in <> "" + dis.pcsn IN 输入.pcsn_in + ENDOPTION + + + OPTION 输入.vbeln_in <> "" + dtl.vbeln IN 输入.vbeln_in + ENDOPTION + + + OPTION 输入.box_no_in <> "" + dis.box_no IN 输入.box_no_in + ENDOPTION + OPTION 输入.cust_code <> "" (cu.cust_code like 输入.cust_code or cu.cust_simple_name like 输入.cust_code) @@ -736,14 +778,26 @@ sub.sap_pcsn like 输入.sap_pcsn ENDOPTION - OPTION 输入.package_box_sn <> "" - sub.package_box_sn like 输入.package_box_sn + OPTION 输入.sap_pcsn_in <> "" + sub.sap_pcsn IN 输入.sap_pcsn_in + ENDOPTION + + OPTION 输入.box_no <> "" + sub.package_box_sn like 输入.box_no + ENDOPTION + + OPTION 输入.box_no_in <> "" + sub.package_box_sn IN 输入.box_no_in ENDOPTION OPTION 输入.pcsn <> "" ivt.pcsn like 输入.pcsn ENDOPTION + OPTION 输入.pcsn_in <> "" + ivt.pcsn IN 输入.pcsn_in + ENDOPTION + OPTION 输入.begin_time <> "" ivt.instorage_time >= 输入.begin_time ENDOPTION @@ -752,10 +806,6 @@ ivt.instorage_time <= 输入.end_time ENDOPTION - OPTION 输入.box_no <> "" - attr.storagevehicle_code = 输入.box_no - ENDOPTION - OPTION 输入.canuse_qty <> "" ivt.canuse_qty > 输入.canuse_qty ENDOPTION @@ -1102,6 +1152,20 @@ point_code1 IN 输入.struct_codes AND task_status IN ('05','06') AND is_delete = '0' + + UNION + + SELECT + point_code1 + FROM + sch_base_task + WHERE + point_code1 IN 输入.struct_codes + AND task_status IN ('07') + AND is_delete = '0' + AND task_type = '010503' + AND DATEDIFF( NOW(), LEFT(update_time,10) ) <= 2 + ENDSELECT ENDQUERY ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/ST_OUTIVT01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/ST_OUTIVT01.wql index 725460a42..ebd2006ad 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/ST_OUTIVT01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/outbill/wql/ST_OUTIVT01.wql @@ -60,7 +60,10 @@ attr.sect_code, attr.sect_name, attr.struct_name, - attr.struct_code + attr.struct_code, + CASE + WHEN DATEDIFF( NOW(), sub.date_of_production ) > '90' THEN '1' ELSE '0' + END AS is_overdue FROM ST_IVT_StructIvt ivt LEFT JOIN ST_IVT_StructAttr attr ON attr.struct_id = ivt.struct_id @@ -159,10 +162,14 @@ attr.sect_code, attr.sect_name, attr.struct_name, - attr.struct_code + attr.struct_code, + CASE + WHEN DATEDIFF( NOW(), sub.date_of_production ) > '90' THEN '1' ELSE '0' + END AS is_overdue FROM ST_IVT_StructIvt ivt LEFT JOIN ST_IVT_StructAttr attr ON attr.struct_id = ivt.struct_id + LEFT JOIN pdm_bi_subpackagerelation sub ON sub.container_name = ivt.pcsn WHERE ivt.quality_scode = '01' AND attr.lock_type = '1' diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/service/impl/InAndOutRetrunServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/service/impl/InAndOutRetrunServiceImpl.java index 5369ebd76..eceaf4d19 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/service/impl/InAndOutRetrunServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/service/impl/InAndOutRetrunServiceImpl.java @@ -45,7 +45,6 @@ public class InAndOutRetrunServiceImpl implements InAndOutReturnService { public Map pageQuery(Map whereJson, Pageable page) { HashMap map = new HashMap<>(whereJson); String bill_code = MapUtil.getStr(whereJson, "bill_code"); - String box_no = MapUtil.getStr(whereJson, "box_no"); String material_search = MapUtil.getStr(whereJson, "material_search"); map.put("flag", "1"); map.put("stor_id", MapUtil.getStr(whereJson, "stor_id")); @@ -55,19 +54,84 @@ public class InAndOutRetrunServiceImpl implements InAndOutReturnService { map.put("is_upload", MapUtil.getStr(whereJson, "is_upload")); map.put("begin_time", MapUtil.getStr(whereJson, "begin_time")); map.put("end_time", MapUtil.getStr(whereJson, "end_time")); - map.put("pcsn", MapUtil.getStr(whereJson, "pcsn")); - map.put("sap_pcsn", MapUtil.getStr(whereJson, "sap_pcsn")); map.put("is_writeoff", MapUtil.getStr(whereJson, "is_writeoff")); - map.put("vbeln", MapUtil.getStr(whereJson, "vbeln")); + + // 空格查询 + String vbeln = MapUtil.getStr(map, "vbeln"); + if (StrUtil.isNotEmpty(vbeln)) { + // 判断是否有空格 + boolean matches = vbeln.matches(".*\\s.*"); + + if (matches) { + String[] s = vbeln.split(" "); + String vbeln_in = String.join("','", Arrays.asList(s)); + + map.put("vbeln_in", "('"+vbeln_in+"')"); + map.put("vbeln", ""); + } else { + map.put("vbeln", "%" + map.get("vbeln") + "%"); + } + } + + // 空格查询 + String box_no = MapUtil.getStr(map, "box_no"); + if (StrUtil.isNotEmpty(box_no)) { + // 判断是否有空格 + + boolean matches = box_no.matches(".*\\s.*"); + + if (matches) { + String[] s = box_no.split(" "); + String box_no_in = String.join("','", Arrays.asList(s)); + + map.put("box_no_in", "('"+box_no_in+"')"); + map.put("box_no", ""); + } else { + map.put("box_no", "%" + map.get("box_no") + "%"); + + } + } + + // 空格查询 + String pcsn = MapUtil.getStr(map, "pcsn"); + if (StrUtil.isNotEmpty(pcsn)) { + // 判断是否有空格 + boolean matches = pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = pcsn.split(" "); + String pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("pcsn_in", "('"+pcsn_in+"')"); + map.put("pcsn", ""); + } else { + map.put("pcsn", "%" + map.get("pcsn") + "%"); + } + } + + // 空格查询 + String sap_pcsn = MapUtil.getStr(map, "sap_pcsn"); + if (StrUtil.isNotEmpty(sap_pcsn)) { + // 判断是否有空格 + boolean matches = sap_pcsn.matches(".*\\s.*"); + + if (matches) { + String[] s = sap_pcsn.split(" "); + String sap_pcsn_in = String.join("','", Arrays.asList(s)); + + map.put("sap_pcsn_in", "('"+sap_pcsn_in+"')"); + map.put("sap_pcsn", ""); + } else { + map.put("sap_pcsn", "%" + map.get("sap_pcsn") + "%"); + } + } + if (!ObjectUtil.isEmpty(bill_code)) { map.put("bill_code", "%" + bill_code + "%"); } if (!ObjectUtil.isEmpty(material_search)) { map.put("material_search", "%" + material_search + "%"); } - if (!ObjectUtil.isEmpty(box_no)) { - map.put("box_no", "%" + box_no + "%"); - } //获取人员对应的仓库 UserStorServiceImpl userStorService = new UserStorServiceImpl(); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/wql/QST_IVT_INANDOUTRETRUN.wql b/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/wql/QST_IVT_INANDOUTRETRUN.wql index 27bbbd875..0a69c811e 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/wql/QST_IVT_INANDOUTRETRUN.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/st/returns/wql/QST_IVT_INANDOUTRETRUN.wql @@ -35,6 +35,10 @@ 输入.ids TYPEAS f_string 输入.box_no TYPEAS s_string 输入.in_stor_id TYPEAS f_string + 输入.pcsn_in TYPEAS f_string + 输入.sap_pcsn_in TYPEAS f_string + 输入.vbeln_in TYPEAS f_string + 输入.box_no_in TYPEAS f_string [临时表] @@ -78,9 +82,15 @@ INNER JOIN md_me_materialbase mb ON mb.material_id = dtl.material_id WHERE 1=1 - OPTION 输入.vbeln <> "" - dtl.vbeln = 输入.vbeln + + OPTION 输入.vbeln <> "" + dtl.vbeln like 输入.vbeln ENDOPTION + + OPTION 输入.vbeln_in <> "" + dtl.vbeln IN 输入.vbeln_in + ENDOPTION + OPTION 输入.material_search <> "" ( mb.material_code like 输入.material_search @@ -100,15 +110,30 @@ AND dis.box_no = sub.package_box_sn AND dis.iostorinv_id = sub.bill_id WHERE 1=1 - OPTION 输入.pcsn <> "" - dis.pcsn = 输入.pcsn + OPTION 输入.pcsn <> "" + dis.pcsn like 输入.pcsn ENDOPTION + + OPTION 输入.pcsn_in <> "" + dis.pcsn IN 输入.pcsn_in + ENDOPTION + OPTION 输入.sap_pcsn <> "" - sub.sap_pcsn = 输入.sap_pcsn + sub.sap_pcsn like 输入.sap_pcsn ENDOPTION + + OPTION 输入.sap_pcsn_in <> "" + sub.sap_pcsn IN 输入.sap_pcsn_in + ENDOPTION + OPTION 输入.box_no <> "" dis.box_no like 输入.box_no - ENDOPTION + ENDOPTION + + OPTION 输入.box_no_in <> "" + dis.box_no IN 输入.box_no_in + ENDOPTION + GROUP BY iostorinv_id ) b ON b.iostorinv_id = mst.iostorinv_id diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/stat/service/impl/OutBillQueryServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/stat/service/impl/OutBillQueryServiceImpl.java index 6370492d6..82ddf84b5 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/stat/service/impl/OutBillQueryServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/stat/service/impl/OutBillQueryServiceImpl.java @@ -295,6 +295,7 @@ public class OutBillQueryServiceImpl implements OutBillQueryService { mp.put("sap批次", json.getString("sap_pcsn")); mp.put("净重", json.getString("net_weight")); mp.put("单位", json.getString("qty_unit_name")); + mp.put("管件类型", json.getString("paper_type")); mp.put("客户编码", json.getString("customer_name")); mp.put("发货客户名称", json.getString("customer_description")); if (ObjectUtil.isEmpty(json.getString("sale_order_name"))) { diff --git a/lms/nladmin-ui/src/views/wms/basedata/st/ivt/index.vue b/lms/nladmin-ui/src/views/wms/basedata/st/ivt/index.vue index 4f3fb44d9..5c7ff08f1 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/st/ivt/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/st/ivt/index.vue @@ -136,6 +136,25 @@ /> + + + + + + + + @@ -292,7 +313,7 @@ const defaultForm = { } export default { name: 'Structivt', - dicts: ['ST_QUALITY_SCODE', 'product_area', 'IS_OR_NOT'], + dicts: ['ST_QUALITY_SCODE', 'product_area', 'IS_OR_NOT', 'SUB_TYPE'], components: { pagination, crudOperation, rrOperation, udOperation, UploadDialog }, mixins: [presenter(), header(), form(defaultForm), crud()], cruds() { @@ -348,6 +369,9 @@ export default { return parseFloat(row[column.property]).toFixed(2) } }, + formatSubType(row) { + return this.dict.label.SUB_TYPE[row.sub_type] + }, // 钩子:在获取表格数据之前执行,false 则代表不获取数据 [CRUD.HOOK.beforeRefresh]() { return true diff --git a/lms/nladmin-ui/src/views/wms/basedata/st/stor/index.vue b/lms/nladmin-ui/src/views/wms/basedata/st/stor/index.vue index b4cbebe95..8397d2dfb 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/st/stor/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/st/stor/index.vue @@ -42,14 +42,8 @@ - - + + @@ -100,13 +94,6 @@ - - - - - - - @@ -292,9 +279,6 @@ export default { stor_name: [ { required: true, message: '仓库名称不能为空', trigger: 'blur' } ], - sysdeptid: [ - { required: true, message: '所属部门不能为空', trigger: 'blur' } - ], stor_capacity: [ { required: false, message: '不能为空', trigger: 'blur' }, { validator: numberOne } diff --git a/lms/nladmin-ui/src/views/wms/basedata/st/struct/OneCreateDialog.vue b/lms/nladmin-ui/src/views/wms/basedata/st/struct/OneCreateDialog.vue new file mode 100644 index 000000000..5d77938be --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/basedata/st/struct/OneCreateDialog.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/basedata/st/struct/index.vue b/lms/nladmin-ui/src/views/wms/basedata/st/struct/index.vue index be120c759..a8398f5a9 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/st/struct/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/st/struct/index.vue @@ -59,7 +59,18 @@ - + + + 一键生成 + + + + @@ -271,6 +284,7 @@ import rrOperation from '@crud/RR.operation' import crudOperation from '@crud/CRUD.operation' import udOperation from '@crud/UD.operation' import pagination from '@crud/Pagination' +import OneCreateDialog from '@/views/wms/basedata/st/struct/OneCreateDialog' import crudSectattr from '@/views/wms/basedata/st/sect/sectattr' import crudUserStor, { getSect } from '@/views/wms/basedata/st/userStor/userStor' /* import checkoutbill from "@/api/wms/st/core/outbill/checkoutbill";*/ @@ -323,7 +337,7 @@ const defaultForm = { export default { name: 'Structattr', dicts: ['ST_HEIGHT_TYPE', 'is_used', 'd_lock_type', 'SCH_TASK_TYPE_DTL', 'placement_type'], - components: { pagination, crudOperation, rrOperation, udOperation }, + components: { pagination, crudOperation, rrOperation, udOperation, OneCreateDialog }, mixins: [presenter(), header(), form(defaultForm), crud()], cruds() { return CRUD({ @@ -349,6 +363,7 @@ export default { } } return { + openOneCreateDialog: false, sects: [], invtypelist: [], permission: {}, @@ -413,6 +428,9 @@ export default { sectChange(val) { this.form.sect_id = val[1] }, + openOneCreate() { + this.openOneCreateDialog = true + }, invtypeFormat(row) { for (const item of this.invtypelist) { if (item.code === row.inv_type) { diff --git a/lms/nladmin-ui/src/views/wms/basedata/st/struct/structattr.js b/lms/nladmin-ui/src/views/wms/basedata/st/struct/structattr.js index fbcd30c8e..1f0e417e8 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/st/struct/structattr.js +++ b/lms/nladmin-ui/src/views/wms/basedata/st/struct/structattr.js @@ -32,4 +32,20 @@ export function changeActive(data) { }) } -export default { add, edit, del, changeActive } +export function oneCreate(data) { + return request({ + url: 'api/structattr/oneCreate', + method: 'post', + data + }) +} + +export function blurQuery(data) { + return request({ + url: 'api/structattr/blurQuery', + method: 'post', + data + }) +} + +export default { add, edit, del, changeActive, oneCreate, blurQuery } diff --git a/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/AddDialog.vue b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/AddDialog.vue index fac90b93f..d103aea66 100644 --- a/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/AddDialog.vue +++ b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/AddDialog.vue @@ -152,6 +152,16 @@ > 添加库存物料 + + 物料信息导入 + @@ -217,6 +227,7 @@ + @@ -226,6 +237,7 @@ import AddDtl from '@/views/wms/st/inStor/productscrap/AddDtl' import productscrap from '@/views/wms/st/inStor/productscrap/productscrap' import StructDiv from '@/views/wms/pub/StructDialog' import crudUserStor from '@/views/wms/basedata/st/userStor/userStor' +import UploadDialog from '@/views/wms/st/inStor/productscrap/UploadDialog' const defaultForm = { bill_code: '', @@ -243,7 +255,7 @@ const defaultForm = { } export default { name: 'AddDialog', - components: { AddDtl, StructDiv }, + components: { AddDtl, StructDiv, UploadDialog }, mixins: [crud(), form(defaultForm)], props: { dialogShow: { @@ -255,12 +267,14 @@ export default { data() { return { dialogVisible: false, + viewShow: false, dtlShow: false, structShow: false, structShow2: false, flagnow: false, nowrow: {}, nowindex: '', + paramViewShow: '', storlist: [], invtypelist: [], storId: null, @@ -461,6 +475,13 @@ export default { this.form.tableData.splice(i, 1, this.form.tableData[i]) } } + }, + Import() { + if (!this.form.stor_id) { + return this.crud.notify('请先选择仓库!', CRUD.NOTIFICATION_TYPE.INFO) + } + this.paramViewShow = this.form.stor_id + this.viewShow = true } } } diff --git a/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/UploadDialog.vue b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/UploadDialog.vue new file mode 100644 index 000000000..74be6ec88 --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/UploadDialog.vue @@ -0,0 +1,120 @@ + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/index.vue b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/index.vue index d56bc41b3..46295ba90 100644 --- a/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/index.vue +++ b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/index.vue @@ -159,6 +159,7 @@ + diff --git a/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/productscrap.js b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/productscrap.js index 7cf5204f2..2f374ccd4 100644 --- a/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/productscrap.js +++ b/lms/nladmin-ui/src/views/wms/st/inStor/productscrap/productscrap.js @@ -59,4 +59,11 @@ export function onSubmit(data) { data }) } -export default { add, edit, del, getOutBillDtl, auditPass, auditOut, onSubmit } +export function excelImport(data) { + return request({ + url: 'api/productscrap/importExcel', + method: 'post', + data + }) +} +export default { add, edit, del, getOutBillDtl, auditPass, auditOut, onSubmit, excelImport } diff --git a/lms/nladmin-ui/src/views/wms/st/inbill/index.vue b/lms/nladmin-ui/src/views/wms/st/inbill/index.vue index 1ded6855f..c28b8c827 100644 --- a/lms/nladmin-ui/src/views/wms/st/inbill/index.vue +++ b/lms/nladmin-ui/src/views/wms/st/inbill/index.vue @@ -103,6 +103,24 @@ /> + + + + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/outbill/DivDialog.vue b/lms/nladmin-ui/src/views/wms/st/outbill/DivDialog.vue index 00a0835ff..2f9a18098 100644 --- a/lms/nladmin-ui/src/views/wms/st/outbill/DivDialog.vue +++ b/lms/nladmin-ui/src/views/wms/st/outbill/DivDialog.vue @@ -256,6 +256,8 @@ + + @@ -282,7 +284,7 @@ export default { name: 'DivDialog', components: { PointDialog, StructIvt }, mixins: [crud()], - dicts: ['io_bill_status', 'ST_QUALITY_SCODE', 'ST_IVT_LEVEL', 'is_used', 'work_status', 'is_usable'], + dicts: ['io_bill_status', 'ST_QUALITY_SCODE', 'ST_IVT_LEVEL', 'is_used', 'work_status', 'is_usable', 'IS_OR_NOT'], props: { dialogShow: { type: Boolean, @@ -387,6 +389,9 @@ export default { ivt_levelFormat(row, column) { return this.dict.label.ST_IVT_LEVEL[row.ivt_level] }, + formatOverdue(row, column) { + return this.dict.label.IS_OR_NOT[row.is_overdue] + }, is_activeFormat(row, column) { return this.dict.label.is_usable[row.is_active] }, diff --git a/lms/nladmin-ui/src/views/wms/st/outbill/ViewDialog.vue b/lms/nladmin-ui/src/views/wms/st/outbill/ViewDialog.vue index 1e424ea58..8b6a56886 100644 --- a/lms/nladmin-ui/src/views/wms/st/outbill/ViewDialog.vue +++ b/lms/nladmin-ui/src/views/wms/st/outbill/ViewDialog.vue @@ -166,7 +166,9 @@ - + + + @@ -187,7 +189,7 @@ export default { name: 'ViewDialog', components: { }, mixins: [crud()], - dicts: ['io_bill_status', 'work_status', 'task_status', 'SCH_TASK_TYPE_DTL','ST_INV_OUT_TYPE', 'INANDOUT_BILL_TYPE'], + dicts: ['io_bill_status', 'work_status', 'task_status', 'SCH_TASK_TYPE_DTL','ST_INV_OUT_TYPE', 'INANDOUT_BILL_TYPE', 'IS_OR_NOT'], props: { dialogShow: { type: Boolean, @@ -246,6 +248,9 @@ export default { taskdtl_typeFormat(row) { return this.dict.label.SCH_TASK_TYPE_DTL[row.taskdtl_type] }, + formatOverdue(row, column) { + return this.dict.label.IS_OR_NOT[row.is_overdue] + }, task_statusFormat(row) { return this.dict.label.task_status[row.task_status] }, diff --git a/lms/nladmin-ui/src/views/wms/st/outbill/index.vue b/lms/nladmin-ui/src/views/wms/st/outbill/index.vue index 5282bafa4..8362bc70a 100644 --- a/lms/nladmin-ui/src/views/wms/st/outbill/index.vue +++ b/lms/nladmin-ui/src/views/wms/st/outbill/index.vue @@ -104,6 +104,15 @@ @keyup.enter.native="crud.toQuery" /> + + +