public async Task Should_Error_Create_Data_False_Conversion() { ExternalPurchaseOrderViewModel viewModel = await DataUtil.GetNewDataViewModel("dev2"); foreach (var item in viewModel.items) { foreach (var detail in item.details) { detail.defaultUom = detail.dealUom; detail.conversion = 2; } } var response = await this.Client.PostAsync(URI, new StringContent(JsonConvert.SerializeObject(viewModel).ToString(), Encoding.UTF8, MediaType)); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); }
public async Task Should_Error_Create_Invalid_Data() { ExternalPurchaseOrderViewModel viewModel = await DataUtil.GetNewDataViewModel("dev2"); viewModel.orderDate = DateTimeOffset.MinValue; viewModel.currency = null; viewModel.unit = null; viewModel.supplier = null; viewModel.items = new List <ExternalPurchaseOrderItemViewModel> { }; HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(viewModel).ToString(), Encoding.UTF8, MediaType); httpContent.Headers.Add("x-timezone-offset", "0"); var response = await this.Client.PostAsync(URI, httpContent); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); }
private ExternalPurchaseOrderViewModel GetExternalPurchaseOrderNo(string id) { string epoUri = "external-purchase-orders"; IHttpClientService httpClient = (IHttpClientService)this.ServiceProvider.GetService(typeof(IHttpClientService)); var response = httpClient.GetAsync($"{APIEndpoint.Purchasing}{epoUri}/{id}").Result; if (response.IsSuccessStatusCode) { var content = response.Content.ReadAsStringAsync().Result; Dictionary <string, object> result = JsonConvert.DeserializeObject <Dictionary <string, object> >(content); ExternalPurchaseOrderViewModel epo = JsonConvert.DeserializeObject <ExternalPurchaseOrderViewModel>(result.GetValueOrDefault("data").ToString()); return(epo); } else { return(null); } }
public async Task Should_Error_Duplicate_Item() { ExternalPurchaseOrderViewModel viewModel = await DataUtil.GetNewDuplicateDataViewModel("dev2"); var item = viewModel.items.FirstOrDefault(); var detail = item.details.FirstOrDefault(); detail.conversion = 0; detail.productPrice = 0; detail.priceBeforeTax = double.MaxValue; item.details.Add(detail); viewModel.items.Add(item); HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(viewModel).ToString(), Encoding.UTF8, MediaType); httpContent.Headers.Add("x-timezone-offset", "0"); var response = await this.Client.PostAsync(URI, httpContent); Assert.NotNull(response); }
public IActionResult Get(int id) { try { var indexAcceptPdf = Request.Headers["Accept"].ToList().IndexOf("application/pdf"); ExternalPurchaseOrder model = _facade.ReadModelById(id); ExternalPurchaseOrderViewModel viewModel = _mapper.Map <ExternalPurchaseOrderViewModel>(model); if (viewModel == null) { throw new Exception("Invalid Id"); } if (indexAcceptPdf < 0) { return(Ok(new { apiVersion = ApiVersion, statusCode = General.OK_STATUS_CODE, message = General.OK_MESSAGE, data = viewModel, })); } else { int clientTimeZoneOffset = int.Parse(Request.Headers["x-timezone-offset"].First()); ExternalPurchaseOrderPDFTemplate PdfTemplate = new ExternalPurchaseOrderPDFTemplate(); MemoryStream stream = PdfTemplate.GeneratePdfTemplate(viewModel, clientTimeZoneOffset); return(new FileStreamResult(stream, "application/pdf") { FileDownloadName = $"{viewModel.no}.pdf" }); } } catch (Exception e) { Dictionary <string, object> Result = new ResultFormatter(ApiVersion, General.INTERNAL_ERROR_STATUS_CODE, e.Message) .Fail(); return(StatusCode(General.INTERNAL_ERROR_STATUS_CODE, Result)); } }
public async Task Should_Error_Update_Invalid_Data() { ExternalPurchaseOrder model = await DataUtil.GetTestData("dev2"); var responseGetById = await this.Client.GetAsync($"{URI}/{model.Id}"); var json = await responseGetById.Content.ReadAsStringAsync(); Dictionary <string, object> result = JsonConvert.DeserializeObject <Dictionary <string, object> >(json.ToString()); Assert.True(result.ContainsKey("apiVersion")); Assert.True(result.ContainsKey("message")); Assert.True(result.ContainsKey("data")); Assert.True(result["data"].GetType().Name.Equals("JObject")); ExternalPurchaseOrderViewModel viewModel = JsonConvert.DeserializeObject <ExternalPurchaseOrderViewModel>(result.GetValueOrDefault("data").ToString()); viewModel.orderDate = DateTimeOffset.MinValue; viewModel.supplier = null; viewModel.unit = null; viewModel.currency = null; viewModel.items = new List <ExternalPurchaseOrderItemViewModel> { }; var response = await this.Client.PutAsync($"{URI}/{model.Id}", new StringContent(JsonConvert.SerializeObject(viewModel).ToString(), Encoding.UTF8, MediaType)); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); //ExternalPurchaseOrderViewModel viewModel2 = JsonConvert.DeserializeObject<ExternalPurchaseOrderViewModel>(result.GetValueOrDefault("data").ToString()); //viewModel2.useIncomeTax = true; //viewModel2.incomeTax = new Lib.ViewModels.IntegrationViewModel.IncomeTaxViewModel //{ // name = "income", // _id = "1", // rate = "2" //}; //viewModel2.incomeTaxBy = ""; //var response2 = await this.Client.PutAsync($"{URI}/{model.Id}", new StringContent(JsonConvert.SerializeObject(viewModel2).ToString(), Encoding.UTF8, MediaType)); //Assert.Equal(HttpStatusCode.BadRequest, response2.StatusCode); }
public async Task Should_Error_Update_Product_Price_less_than_dealPrice_Data() { ExternalPurchaseOrder model = await DataUtil.GetTestData("dev2"); var responseGetById = await this.Client.GetAsync($"{URI}/{model.Id}"); var json = await responseGetById.Content.ReadAsStringAsync(); Dictionary <string, object> result = JsonConvert.DeserializeObject <Dictionary <string, object> >(json.ToString()); Assert.True(result.ContainsKey("apiVersion")); Assert.True(result.ContainsKey("message")); Assert.True(result.ContainsKey("data")); Assert.True(result["data"].GetType().Name.Equals("JObject")); ExternalPurchaseOrderViewModel viewModel = JsonConvert.DeserializeObject <ExternalPurchaseOrderViewModel>(result.GetValueOrDefault("data").ToString()); viewModel.incomeTax = new Lib.ViewModels.IntegrationViewModel.IncomeTaxViewModel { _id = "1", name = "test", rate = "1" }; viewModel.incomeTaxBy = null; foreach (var item in viewModel.items) { foreach (var detail in item.details) { detail.productPrice = 1; detail.pricePerDealUnit = 10000; detail.dealQuantity = 0; } } var response = await this.Client.PutAsync($"{URI}/{model.Id}", new StringContent(JsonConvert.SerializeObject(viewModel).ToString(), Encoding.UTF8, MediaType)); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); }
public async Task <IActionResult> Post([FromBody] ExternalPurchaseOrderViewModel vm) { identityService.Token = Request.Headers["Authorization"].First().Replace("Bearer ", ""); identityService.Username = User.Claims.Single(p => p.Type.Equals("username")).Value; ExternalPurchaseOrder m = _mapper.Map <ExternalPurchaseOrder>(vm); ValidateService validateService = (ValidateService)_facade.serviceProvider.GetService(typeof(ValidateService)); try { validateService.Validate(vm); int clientTimeZoneOffset = int.Parse(Request.Headers["x-timezone-offset"].First()); int result = await _facade.Create(m, identityService.Username, clientTimeZoneOffset); Dictionary <string, object> Result = new ResultFormatter(ApiVersion, General.CREATED_STATUS_CODE, General.OK_MESSAGE) .Ok(); return(Created(String.Concat(Request.Path, "/", 0), Result)); } catch (ServiceValidationExeption e) { Dictionary <string, object> Result = new ResultFormatter(ApiVersion, General.BAD_REQUEST_STATUS_CODE, General.BAD_REQUEST_MESSAGE) .Fail(e); return(BadRequest(Result)); } catch (Exception e) { Dictionary <string, object> Result = new ResultFormatter(ApiVersion, General.INTERNAL_ERROR_STATUS_CODE, e.Message) .Fail(); return(StatusCode(General.INTERNAL_ERROR_STATUS_CODE, Result)); } }
public MemoryStream GeneratePdfTemplate(ExternalPurchaseOrderViewModel viewModel, int clientTimeZoneOffset) { Font header_font = FontFactory.GetFont(BaseFont.HELVETICA, BaseFont.CP1250, BaseFont.NOT_EMBEDDED, 18); Font normal_font = FontFactory.GetFont(BaseFont.HELVETICA, BaseFont.CP1250, BaseFont.NOT_EMBEDDED, 10); Font bold_font = FontFactory.GetFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1250, BaseFont.NOT_EMBEDDED, 10); Document document = new Document(PageSize.A4, 40, 40, 40, 40); MemoryStream stream = new MemoryStream(); PdfWriter writer = PdfWriter.GetInstance(document, stream); document.Open(); #region Header PdfPTable tableHeader = new PdfPTable(2); tableHeader.SetWidths(new float[] { 4f, 4f }); PdfPCell cellHeaderContentLeft = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_LEFT }; PdfPCell cellHeaderContentRight = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_RIGHT }; cellHeaderContentLeft.Phrase = new Phrase("PT DAN LIRIS" + "\n" + "Head Office: Kelurahan Banaran" + "\n" + "Kecamatan Grogol" + "\n" + "Sukoharjo 57193 - INDONESIA" + "\n" + "PO.BOX 166 Solo 57100" + "\n" + "Telp. (0271) 740888, 714400" + "\n" + "Fax. (0271) 735222, 740777", bold_font); tableHeader.AddCell(cellHeaderContentLeft); cellHeaderContentRight.Phrase = new Phrase("FM-PB-00-06-009/R1" + "\n" + "Nomor PO: " + viewModel.no, bold_font); tableHeader.AddCell(cellHeaderContentRight); PdfPCell cellHeader = new PdfPCell(tableHeader); // dont remove tableHeader.ExtendLastRow = false; tableHeader.SpacingAfter = 10f; document.Add(tableHeader); string titleString = "ORDER PEMBELIAN"; bold_font.SetStyle(Font.UNDERLINE); Paragraph title = new Paragraph(titleString, bold_font) { Alignment = Element.ALIGN_CENTER }; document.Add(title); bold_font.SetStyle(Font.NORMAL); #endregion #region Identity PdfPTable tableIdentity = new PdfPTable(3); tableIdentity.SetWidths(new float[] { 1f, 4.5f, 2.5f }); PdfPCell cellIdentityContentLeft = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_LEFT }; PdfPCell cellIdentityContentRight = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_RIGHT }; cellIdentityContentLeft.Phrase = new Phrase("Kepada Yth", normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentLeft.Phrase = new Phrase(": " + viewModel.supplier.name, normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentRight.Phrase = new Phrase("Sukoharjo, " + viewModel.orderDate.ToOffset(new TimeSpan(clientTimeZoneOffset, 0, 0)).ToString("dd MMMM yyyy", new CultureInfo("id-ID")), normal_font); tableIdentity.AddCell(cellIdentityContentRight); cellIdentityContentLeft.Phrase = new Phrase(" ", normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentLeft.Phrase = new Phrase(" " + "Attn.", normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentRight.Phrase = new Phrase("Mohon di-fax kembali setelah", normal_font); tableIdentity.AddCell(cellIdentityContentRight); cellIdentityContentLeft.Phrase = new Phrase(" ", normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentLeft.Phrase = new Phrase(" " + "Telp.", normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentRight.Phrase = new Phrase("ditandatangani dan distempel", normal_font); tableIdentity.AddCell(cellIdentityContentRight); cellIdentityContentLeft.Phrase = new Phrase(" ", normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentLeft.Phrase = new Phrase(" " + " ", normal_font); tableIdentity.AddCell(cellIdentityContentLeft); cellIdentityContentRight.Phrase = new Phrase("perusahaan. Terima Kasih.", normal_font); tableIdentity.AddCell(cellIdentityContentRight); PdfPCell cellIdentity = new PdfPCell(tableIdentity); // dont remove tableIdentity.ExtendLastRow = false; document.Add(tableIdentity); #endregion document.Add(new Paragraph("Dengan Hormat,", normal_font) { Alignment = Element.ALIGN_LEFT }); string firstParagraphString = "Yang bertanda tangan di bawah ini, PT. DAN LIRIS, SOLO (selanjutnya disebut sebagai pihak Pembeli) dan " + viewModel.supplier.name + "(selanjutnya disebut sebagai pihak Penjual) saling menyetujui untuk mengadaan kontrak jual beli dengan ketentuan sebagai berikut : "; Paragraph firstParagraph = new Paragraph(firstParagraphString, normal_font) { Alignment = Element.ALIGN_LEFT }; firstParagraph.SpacingBefore = 10f; firstParagraph.SpacingAfter = 10f; document.Add(firstParagraph); #region Items PdfPCell cellCenter = new PdfPCell() { Border = Rectangle.TOP_BORDER | Rectangle.LEFT_BORDER | Rectangle.BOTTOM_BORDER | Rectangle.RIGHT_BORDER, HorizontalAlignment = Element.ALIGN_CENTER, VerticalAlignment = Element.ALIGN_MIDDLE, Padding = 5 }; PdfPCell cellRight = new PdfPCell() { Border = Rectangle.TOP_BORDER | Rectangle.LEFT_BORDER | Rectangle.BOTTOM_BORDER | Rectangle.RIGHT_BORDER, HorizontalAlignment = Element.ALIGN_RIGHT, VerticalAlignment = Element.ALIGN_MIDDLE, Padding = 5 }; PdfPCell cellLeft = new PdfPCell() { Border = Rectangle.TOP_BORDER | Rectangle.LEFT_BORDER | Rectangle.BOTTOM_BORDER | Rectangle.RIGHT_BORDER, HorizontalAlignment = Element.ALIGN_LEFT, VerticalAlignment = Element.ALIGN_MIDDLE, Padding = 5 }; PdfPTable tableContent = new PdfPTable(4); tableContent.SetWidths(new float[] { 7f, 4f, 4f, 4f }); cellCenter.Phrase = new Phrase("NAMA DAN JENIS BARANG", bold_font); tableContent.AddCell(cellCenter); cellCenter.Phrase = new Phrase("JUMLAH", bold_font); tableContent.AddCell(cellCenter); cellCenter.Phrase = new Phrase("HARGA SATUAN", bold_font); tableContent.AddCell(cellCenter); cellCenter.Phrase = new Phrase("SUB TOTAL", bold_font); tableContent.AddCell(cellCenter); double total = 0; //for (int a = 0; a < 20; a++) // coba kalau banyak baris ^_^ foreach (ExternalPurchaseOrderItemViewModel item in viewModel.items) { for (int indexItem = 0; indexItem < item.details.Count; indexItem++) { ExternalPurchaseOrderDetailViewModel detail = item.details[indexItem]; string line1 = detail.product.name + "\n"; string line2 = detail.productRemark + "\n"; string line3 = item.prNo; Paragraph p1 = new Paragraph(); Phrase ph1 = new Phrase(line1, normal_font); Phrase ph2 = new Phrase(line2, normal_font); Phrase ph3 = new Phrase(line3, normal_font); p1.Add(ph1); p1.Add(ph2); p1.Add(ph3); tableContent.AddCell(p1); cellLeft.Phrase = new Phrase($"{detail.dealQuantity} {detail.dealUom.unit}", normal_font); tableContent.AddCell(cellLeft); cellCenter.Phrase = new Phrase($"{viewModel.currency.code} {detail.pricePerDealUnit.ToString("N", new CultureInfo("id-ID"))}", normal_font); tableContent.AddCell(cellCenter); double subtotalPrice = detail.pricePerDealUnit * detail.dealQuantity; cellCenter.Phrase = new Phrase($"{viewModel.currency.code} {subtotalPrice.ToString("N", new CultureInfo("id-ID"))}", normal_font); tableContent.AddCell(cellCenter); total += subtotalPrice; } } cellRight.Colspan = 3; cellRight.Phrase = new Phrase("Total", bold_font); tableContent.AddCell(cellRight); cellLeft.Phrase = new Phrase($"{viewModel.currency.code} {total.ToString("N", new CultureInfo("id-ID"))}", normal_font); tableContent.AddCell(cellLeft); cellRight.Colspan = 3; cellRight.Phrase = new Phrase("PPN 10%", bold_font); tableContent.AddCell(cellRight); string ppn = ""; double ppnNominal = 0; if (viewModel.useVat) { ppnNominal = total * 10 / 100; ppn = $"{viewModel.currency.code} {ppnNominal.ToString("N", new CultureInfo("id-ID"))}"; } cellLeft.Phrase = new Phrase(ppn, normal_font); tableContent.AddCell(cellLeft); cellRight.Colspan = 3; cellRight.Phrase = new Phrase("Grand Total", bold_font); tableContent.AddCell(cellRight); cellLeft.Phrase = new Phrase($"{viewModel.currency.code} {(total+ ppnNominal).ToString("N", new CultureInfo("id-ID"))}", normal_font); tableContent.AddCell(cellLeft); PdfPCell cellContent = new PdfPCell(tableContent); // dont remove tableContent.ExtendLastRow = false; tableContent.SpacingAfter = 20f; document.Add(tableContent); #endregion #region Footer PdfPTable tableFooter = new PdfPTable(4); tableFooter.SetWidths(new float[] { 3f, 7f, 3f, 4f }); //PdfPCell cellFooterContentLeft = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_LEFT }; //PdfPCell cellFooterContentRight = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_RIGHT }; PdfPCell cellFooterContent = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_LEFT }; cellFooterContent.Phrase = new Phrase("Ongkos Kirim", normal_font); tableFooter.AddCell(cellFooterContent); cellFooterContent.Phrase = new Phrase(": " + viewModel.freightCostBy, normal_font); tableFooter.AddCell(cellFooterContent); cellFooterContent.Phrase = new Phrase("Delivery", normal_font); tableFooter.AddCell(cellFooterContent); cellFooterContent.Phrase = new Phrase(": " + (viewModel.deliveryDate.ToOffset(new TimeSpan(clientTimeZoneOffset, 0, 0)).ToString("dd MMMM yyyy", new CultureInfo("id-ID"))), normal_font); tableFooter.AddCell(cellFooterContent); string duedays = ""; if (Convert.ToInt32(viewModel.paymentDueDays) > 0) { duedays = viewModel.paymentDueDays + " hari setelah terima barang"; } cellFooterContent.Phrase = new Phrase("Pembayaran", normal_font); tableFooter.AddCell(cellFooterContent); cellFooterContent.Phrase = new Phrase(": " + viewModel.paymentMethod + "\n" + " " + duedays, normal_font); tableFooter.AddCell(cellFooterContent); cellFooterContent.Phrase = new Phrase("Lain-lain", normal_font); tableFooter.AddCell(cellFooterContent); cellFooterContent.Phrase = new Phrase(": " + viewModel.remark, normal_font); tableFooter.AddCell(cellFooterContent); PdfPCell cellFooter = new PdfPCell(tableFooter); // dont remove tableFooter.ExtendLastRow = false; tableContent.SpacingAfter = 20f; document.Add(tableFooter); #endregion #region TableSignature PdfPTable tableSignature = new PdfPTable(2); PdfPCell cellSignatureContent = new PdfPCell() { Border = Rectangle.NO_BORDER, HorizontalAlignment = Element.ALIGN_CENTER }; cellSignatureContent.Phrase = new Phrase("Pembeli\n\n\n\n\n\n\n( " + viewModel.CreatedBy + " )", bold_font); tableSignature.AddCell(cellSignatureContent); cellSignatureContent.Phrase = new Phrase("Penjual\n\n\n\n\n\n\n( " + viewModel.supplier.name + " )", bold_font); tableSignature.AddCell(cellSignatureContent); PdfPCell cellSignature = new PdfPCell(tableSignature); // dont remove tableSignature.ExtendLastRow = false; tableSignature.SpacingBefore = 20f; tableSignature.SpacingAfter = 20f; document.Add(tableSignature); #endregion document.Close(); byte[] byteInfo = stream.ToArray(); stream.Write(byteInfo, 0, byteInfo.Length); stream.Position = 0; return(stream); }
public ExternalPurchaseOrderViewModel GetNewData() { long nowTicks = DateTimeOffset.Now.Ticks; var data = new ExternalPurchaseOrderViewModel { currency = new CurrencyViewModel { code = "CurrencyCode", description = "description", rate = 0.5, _id = "CurrencyId" }, unit = new UnitViewModel { code = "UnitCode", division = new DivisionViewModel { code = "DivisionCode", name = "DivisionName", _id = "DivisionId" }, name = "UnitName", _id = "UnitId" }, no = "EPONo", freightCostBy = "test", deliveryDate = DateTime.Now.AddDays(1), orderDate = DateTime.Now, supplier = new SupplierViewModel { code = "sup", name = "Supplier", _id = "supId" }, incomeTax = new IncomeTaxViewModelEPO { name = "Final", rate = "1.5", }, useIncomeTax = true, incomeTaxBy = "Supplier", paymentMethod = "test", remark = "Remark", Active = true, CreatedAgent = null, isClosed = false, CreatedBy = null, CreatedUtc = new DateTime(), division = new DivisionViewModel { code = null, name = null, _id = null }, Id = 1, isCanceled = false, IsDeleted = false, isPosted = false, LastModifiedAgent = null, LastModifiedBy = null, LastModifiedUtc = new DateTime(), paymentDueDays = null, UId = null, useVat = false, items = new List <ExternalPurchaseOrderItemViewModel> { new ExternalPurchaseOrderItemViewModel { poId = 1, poNo = $"PONo{nowTicks}", prId = 1, prNo = $"PRNo{nowTicks}", unit = new UnitViewModel { code = "unitcode", name = "unit", _id = "unitId" }, Active = true, CreatedAgent = null, CreatedBy = null, CreatedUtc = new DateTime(), LastModifiedAgent = null, LastModifiedBy = null, LastModifiedUtc = new DateTime(), Id = 1, IsDeleted = false, details = new List <ExternalPurchaseOrderDetailViewModel> { new ExternalPurchaseOrderDetailViewModel { Active = true, CreatedAgent = null, CreatedBy = null, CreatedUtc = new DateTime(), LastModifiedAgent = null, LastModifiedBy = null, LastModifiedUtc = new DateTime(), dispositionQuantity = 0, Id = 1, doQuantity = 0, includePpn = false, IsDeleted = false, productPrice = 0, poItemId = 1, prItemId = 1, product = new ProductViewModel { _id = "ProductId", code = "ProductCode", name = "ProductName", }, defaultQuantity = 1, dealUom = new UomViewModel { unit = "Uom", _id = "UomId" }, defaultUom = new UomViewModel { unit = "Uom", _id = "UomId" }, productRemark = "Remark", priceBeforeTax = 1000, pricePerDealUnit = 200, dealQuantity = 1, conversion = 1 } } } } }; return(data); }