Skip to content

Instantly share code, notes, and snippets.

@ahmed-abdelazim
Created January 25, 2021 11:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahmed-abdelazim/2fa58a4447b8b3f30a24aaa771dad0d5 to your computer and use it in GitHub Desktop.
Save ahmed-abdelazim/2fa58a4447b8b3f30a24aaa771dad0d5 to your computer and use it in GitHub Desktop.
pdf writer
<!doctype html>
<html ng-app="app">
<head>
</head>
<body>
<div ng-controller="LayoutViewController as $ctrl" class="container">
<div class="row">
<div class="col-md-9">
<button ng-click="$ctrl.genPDF2()">Generate PDF (client side only)</button>
&nbsp;
&nbsp;
&nbsp;
<button ng-click="$ctrl.genAPI2PDF()">Generate PDF (using JS api2pdf)</button>
<div class="a4 grid-container" >
<div class="Title">
<b>INVOICE<span style="font-size:75%"> RECHNUNG FACTURE FACTURA</span></b>
</div>
<div class="lt tp rt bt Seller"><label for="seller">Seller</label>
<!-- <textarea ng-focus-model id="seller" name="seller" type="text" ng-pattern="" ng-model="$ctrl.trade.adata.invoices[0].seller_and_address"
required>
</textarea> -->
<img src="https://www.exabler.com/images/exabler.png" width="100%">
</div>
<div class=" tp rt Admin">
<div class="rt bt InvoiceDate">
<label for="invoice_date">Invoice date</label>
<input ng-focus-model style="display:block" name="invoice_date" type="text" uib-datepicker-popup='{{$ctrl.dateOptions.dateFormat}}'
ng-model="$ctrl.trade.adata.invoices[0].issue_date" ng-value="$ctrl.trade.adata.invoices[0].issue_date | date: '{{$ctrl.dateOptions.dateFormat}}'"
is-open="$ctrl.view.issue_date" ng-click="$ctrl.view.issue_date = true" max-date="maxDate"
datepicker-options="$ctrl.dateOptions" close-text="Close">
<!-- <input ng-focus-model id="Invoice date" type="text" name="Invoice date" ng-model="$ctrl.trade.adata.invoices[0].issue_date" "> -->
</div>
<div class="rt bt BuyerRef"><label for="buyer_reference">Buyer's reference</label>
<input ng-focus-model type="text" name="buyer_reference" ng-model="$ctrl.trade.adata.contract.buyer_ref">
</div>
<div class="rt bt InvoiceNo"><label for="invoice_number">Invoice number</label>
<input ng-focus-model type="text" name="invoice_number" ng-model="$ctrl.trade.adata.invoices[0].invoice_number">
</div>
<div class="bt PageNo"><label for=""></label>Page 1 of 1
</div>
<div class="bt PurchaseOrderDate"><label for="purchase_order_date">Purchase Order date</label>
<input ng-focus-model style="display:block" id="Invoice date" name="purchase_order_date" type="text"
uib-datepicker-popup='{{$ctrl.dateOptions.dateFormat}}' ng-model="$ctrl.trade.adata.contract.sign_date"
ng-value="$ctrl.trade.adata.contract.sign_date | date: '{{$ctrl.dateOptions.dateFormat}}'" is-open="$ctrl.view.po_date"
ng-click="$ctrl.view.po_date = true" max-date="maxDate" datepicker-options="$ctrl.dateOptions"
close-text="Close">
</div>
<div class="bt SellerRef"><label for="seller_reference">Seller's reference</label>
<input ng-focus-model type="text" name="seller_reference" ng-model="$ctrl.trade.adata.contract.seller_ref">
</div>
</div>
<div class="lt rt bt Consignee"><label for="consignee">Consignee</label>
<textarea ng-focus-model type="text" name="consignee" ng-model="$ctrl.trade.adata.shipments[0].consignee_and_address">
</textarea>
<!-- <select type="text" name="Consignee">
</select> -->
</div>
<div class="rt bt Buyer"><label for="buyer">Buyer</label>
<textarea ng-focus-model type="text" name="buyer" ng-model="$ctrl.trade.adata.invoices[0].buyer_and_address">
</textarea>
</div>
<div class=" rt bt lt AdditionalInformation"><label for="additional_info">Additional information</label>
<textarea ng-focus-model type="text" name="additional_info" ng-model="$ctrl.trade.adata.invoices[0].additional_info">
</textarea>
</div>
<div class=" rt bt OriginDestinationBank">
<div class="bt BuyerBank">
<label for="buyer_bank">
<span class="noprint">Buyer's bank</span>
<span ng-if="$ctrl.trade.adata.invoices[0].payment_options=='lc'">Buyer's bank</span>
</label>
<input ng-focus-model type="text" name="buyer_bank" disabled>
</div>
<div class="rt OriginCountry"><label for="origin_country">Origin country</label>
<textarea ng-focus-model type="text" name="origin_country" ng-model="$ctrl.trade.adata.shipments[0].origin_country_text">
</textarea>
</div>
<div class="DestCountry"><label for="destination_country">Destination country</label>
<textarea ng-focus-model type="text" name="destination_country" ng-model="$ctrl.trade.adata.shipments[0].destination_country_text">
</textarea>
</div>
</div>
<div class="lt rt bt Transport">
<div class="rt bt TransportMode"><label for="mode_of_transport">Mode of transport</label>
<textarea ng-focus-model rows="3" type="text" name="mode_of_transport" ng-model="$ctrl.trade.adata.shipments[0].mode.description">
</textarea>
</div>
<!--<div class=" DespatchDate"><label for="">Date of despatch</label><input ng-focus-model type="text" name="Date of despatch">
</div>-->
<div class="rt DepatchPlace"><label for="place_of_despatch">Place of despatch</label>
<textarea ng-focus-model rows="3" type="text" name="place_of_despatch" value="" disabled>
{{$ctrl.trade.adata.shipments[0].origin.address.formatted_address}} {{$ctrl.trade.adata.shipments[0].origin.address.name}}
</textarea>
</div>
<!--
<div class="TransportMean"><label for="">Means of transport</label><input ng-focus-model type="text" name="Means of transport">
</div>
<div class="VesselNo"><label for="">Vessel number</label><input ng-focus-model type="text" name="Vessel number">
</div>
<div class="LoadingPort"><label for="">Loading port</label><input ng-focus-model type="text" name="Loading port">
</div>
<div class="DischargePort"><label for="">Discharge port</label><input ng-focus-model type="text" name="Discharge port">
</div>
-->
<div class="DeliveryPlace"><label for="delivery_place">Delivery place</label>
<textarea ng-focus-model rows="3" type="text" name="delivery_place" disabled>
{{$ctrl.trade.adata.shipments[0].destination.address.formatted_address}} {{$ctrl.trade.adata.shipments[0].destination.address.name}}
</textarea>
</div>
<div class="bt ExtraInfo">
<label for="extra_info">
<!-- <span class="noprint">Extra transport details</span> -->
<span class="noprint" ng-if="$ctrl.trade.adata.shipments[0].additional_transport_info">Extra transport details</span>
</label>
<textarea ng-focus-model rows="3" type="text" name="extra_info" ng-model="$ctrl.trade.adata.shipments[0].additional_transport_info"></textarea>
</div>
</div>
<div class="bt rt Payment">
<div class="bt rt PaymentTerms"><label for="payment_terms">Payment &amp; delivery terms</label>
<textarea ng-focus-model type="text" name="payment_terms" ng-model="$ctrl.trade.adata.invoices[0].terms_full_text"></textarea>
</div>
<div class="bt PaymentCurrency"><label for="payment_currency">Payment currency</label>
<input ng-focus-model type="text" name="payment_currency" ng-model="$ctrl.trade.adata.invoices[0].currency">
</div>
<div class=" SellerBank">
<label for="seller_bank">
<span class="noprint">Seller's bank</span>
<span ng-if="$ctrl.trade.adata.invoices[0].payment_options=='lc'">Seller's bank</span>
</label>
<textarea ng-focus-model type="text" name="seller_bank"></textarea>
</div>
</div>
<div class="lt rt bt Shipping">
<div class="rt ShippingMarks"><label for="shipping_marks">Shipping marks</label>
<textarea ng-focus-model type="text" name="shipping_marks" ng-model="$ctrl.trade.adata.shipments[0].shipping_marks">
</textarea>
</div>
<div class=" rt PackagesDescription"><label for="goods_description">No. and kind of packages; description
of goods</label>
<textarea ng-focus-model type="text" name="goods_description" ng-model="$ctrl.trade.adata.shipments[0].description">
</textarea>
</div>
<div class="Dimensions">
<div class="bt rt GrossWt"><label for="gross_wt">Total gross wt (kg)</label>
<input ng-focus-model fcsa-number type="text" name="gross_wt" ng-model="$ctrl.trade.adata.shipments[0].gross_weight">
</div>
<div class="bt NetWt"><label for="net_wt">Total net wt (kg) </label>
<input ng-focus-model fcsa-number type="text" name="net_wt" ng-model="$ctrl.trade.adata.shipments[0].net_weight">
</div>
<div class="rt GrossVol"><label for="gross_vol">Total cube (m3)</label>
<input ng-focus-model fcsa-number type="text" name="gross_vol" ng-model="$ctrl.trade.adata.shipments[0].volume">
</div>
</div>
</div>
<div item-overflow style="vertical-align: top" class="lt rt bt Items" >
<table style="table-layout:fixed;">
<tr class="ItemsHeadings">
<td class="rt">
#
</td>
<td class="rt">
Description
</td>
<td class="rt">
Commodity Code
</td>
<td class="rt" >
Quantity
</td>
<td class="rt" >
Unit price
</td>
<td>
Amount
</td>
</tr>
<tr ng-repeat="d in $ctrl.trade.adata.shipments[0].items">
<td class="rt" style="width:5%">
{{$index+1}}
</td>
<td class="rt" style="width:43%">
<!-- <textarea type="text" name="item_description" ng-model="d.description"></textarea> -->
<div class="ItemRow" contenteditable ng-blur="$ctrl.resetScrollToTop($event)" ng-model="d.description">
{{d.description}}</div>
<!-- Note - in my implemenation I don't need to have {{}} to populate this field -->
</td>
<td class="rt" style="width:13%">
<!-- <textarea type="text" name="item_description" ng-model="d.HS_code.Code"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.HS_code.Code">{{d.HS_code.Code}}</div>
</td>
<td class="rt" style="width:10%">
<!-- <textarea type="text" name="item_description" ng-model="d.quantity"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.quantity">{{d.quantity}}</div>
</td>
<td class="rt" style="width:10%">
<!-- <textarea type="text" name="item_description" ng-model="d.unit_price"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.unit_price">{{d.unit_price}}</div>
</td>
<td class="rt" style="width:10%">
<!-- <textarea type="text" name="item_description" ng-model="d.amount"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.amount">{{d.amount}}</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="lt bt rt Subtotals">
<div class="lt bt Subtotal"><label for="subtotal">Subtotal</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="subtotal" ng-model="$ctrl.trade.adata.invoices[0].subtotal">
</div>
<div class=" lt bt Charges"><label for="charges">Total charges</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="charges" ng-model="$ctrl.trade.adata.invoices[0].charges">
</div>
<div class=" lt Deductions"><label for="deductions">Total deductions</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="deductions" ng-model="$ctrl.trade.adata.invoices[0].discounts">
</div>
</div>
<div class="lt bt rt Clauses"><label for="clauses_notes">Clauses and/or Notes
</label>
<textarea ng-focus-model type="text" name="clauses_notes" ng-model="$ctrl.trade.adata.invoices[0].clauses_notes">
</textarea>
</div>
<div class="bt rt SummarySign">
<div class="bt Totals"><label for="total_to_pay">Total to pay</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="total_to_pay" ng-model="$ctrl.trade.adata.invoices[0].amount">
</div>
<div class="bt TotalsWords"><label for="total_to_pay_words">Total to pay (in words)</label>
<textarea ng-focus-model style="text-transform:capitalize" name="total_to_pay_words" ng-model="$ctrl.trade.adata.invoices[0].total_words"></textarea>
</div>
<div class="bt box SignatureName"><label for="signatory_name">Name of signatory</label>
<input ng-focus-model type="text" name="signatory_name" ng-model="$ctrl.trade.adata.invoices[0].signatory">
</div>
<div class="bt box PlaceDate"><label for="sig_place_date">Place and date</label>
<input ng-focus-model type="text" name="sig_place_date" ng-model="$ctrl.trade.adata.invoices[0].sig_place_date">
</div>
<div class=" box Signature"><label for="inv_signature">Signature</label>
<input ng-focus-model type="text" name="inv_signature" ng-model="$ctrl.trade.adata.invoice[0].signature">
<!-- blob/image, or else digital signature -->
</div>
</div>
</div>
<div class="a4 landscape grid-container" >
<div class="Title">
<b>INVOICE<span style="font-size:75%"> RECHNUNG FACTURE FACTURA</span></b>
</div>
<div class="lt tp rt bt Seller"><label for="seller">Seller</label>
<textarea ng-focus-model id="seller" name="seller" type="text" ng-pattern="" ng-model="$ctrl.trade.adata.invoices[0].seller_and_address"
required>
</textarea>
</div>
<div class=" tp rt Admin">
<div class="rt bt InvoiceDate">
<label for="invoice_date">Invoice date</label>
<input ng-focus-model style="display:block" name="invoice_date" type="text" uib-datepicker-popup='{{$ctrl.dateOptions.dateFormat}}'
ng-model="$ctrl.trade.adata.invoices[0].issue_date" ng-value="$ctrl.trade.adata.invoices[0].issue_date | date: '{{$ctrl.dateOptions.dateFormat}}'"
is-open="$ctrl.view.issue_date" ng-click="$ctrl.view.issue_date = true" max-date="maxDate"
datepicker-options="$ctrl.dateOptions" close-text="Close">
<!-- <input ng-focus-model id="Invoice date" type="text" uib-datepicker-popup="dd-mm-yyyy" ng-model="$ctrl.trade.adata.invoices[0].issue_date" is-open="view.issue_date2.opened" > -->
<!-- <input ng-focus-model id="Invoice date" type="text" name="Invoice date" ng-model="$ctrl.trade.adata.invoices[0].issue_date" "> -->
</div>
<div class="rt bt BuyerRef"><label for="buyer_reference">Buyer's reference</label>
<input ng-focus-model type="text" name="buyer_reference" ng-model="$ctrl.trade.adata.contract.buyer_ref">
</div>
<div class="rt bt InvoiceNo"><label for="invoice_number">Invoice number</label>
<input ng-focus-model type="text" name="invoice_number" ng-model="$ctrl.trade.adata.invoices[0].invoice_number">
</div>
<div class="bt PageNo"><label for=""></label>Page 1 of 1
</div>
<div class="bt PurchaseOrderDate"><label for="purchase_order_date">Purchase Order date</label>
<input ng-focus-model style="display:block" id="Invoice date" name="purchase_order_date" type="text"
uib-datepicker-popup='{{$ctrl.dateOptions.dateFormat}}' ng-model="$ctrl.trade.adata.contract.sign_date"
ng-value="$ctrl.trade.adata.contract.sign_date | date: '{{$ctrl.dateOptions.dateFormat}}'" is-open="$ctrl.view.po_date"
ng-click="$ctrl.view.po_date = true" max-date="maxDate" datepicker-options="$ctrl.dateOptions"
close-text="Close">
</div>
<div class="bt SellerRef"><label for="seller_reference">Seller's reference</label>
<input ng-focus-model type="text" name="seller_reference" ng-model="$ctrl.trade.adata.contract.seller_ref">
</div>
</div>
<div class="lt rt bt Consignee"><label for="consignee">Consignee</label>
<textarea ng-focus-model type="text" name="consignee" ng-model="$ctrl.trade.adata.shipments[0].consignee_and_address">
</textarea>
<!-- <select type="text" name="Consignee">
</select> -->
</div>
<div class="rt bt Buyer"><label for="buyer">Buyer</label>
<textarea ng-focus-model type="text" name="buyer" ng-model="$ctrl.trade.adata.invoices[0].buyer_and_address">
</textarea>
</div>
<div class=" rt bt lt AdditionalInformation"><label for="additional_info">Additional information</label>
<textarea ng-focus-model type="text" name="additional_info" ng-model="$ctrl.trade.adata.invoices[0].additional_info">
</textarea>
</div>
<div class=" rt bt OriginDestinationBank">
<div class="bt BuyerBank">
<label for="buyer_bank">
<span class="noprint">Buyer's bank</span>
<span ng-if="$ctrl.trade.adata.invoices[0].payment_options=='lc'">Buyer's bank</span>
</label>
<input ng-focus-model type="text" name="buyer_bank" disabled>
</div>
<div class="rt OriginCountry"><label for="origin_country">Origin country</label>
<textarea ng-focus-model type="text" name="origin_country" ng-model="$ctrl.trade.adata.shipments[0].origin_country_text">
</textarea>
</div>
<div class="DestCountry"><label for="destination_country">Destination country</label>
<textarea ng-focus-model type="text" name="destination_country" ng-model="$ctrl.trade.adata.shipments[0].destination_country_text">
</textarea>
</div>
</div>
<div class="lt rt bt Transport">
<div class="rt bt TransportMode"><label for="mode_of_transport">Mode of transport</label>
<textarea ng-focus-model rows="3" type="text" name="mode_of_transport" ng-model="$ctrl.trade.adata.shipments[0].mode.description">
</textarea>
</div>
<!--<div class=" DespatchDate"><label for="">Date of despatch</label><input ng-focus-model type="text" name="Date of despatch">
</div>-->
<div class="rt DepatchPlace"><label for="place_of_despatch">Place of despatch</label>
<textarea ng-focus-model rows="3" type="text" name="place_of_despatch" value="" disabled>
{{$ctrl.trade.adata.shipments[0].origin.address.formatted_address}} {{$ctrl.trade.adata.shipments[0].origin.address.name}}
</textarea>
</div>
<!--
<div class="TransportMean"><label for="">Means of transport</label><input ng-focus-model type="text" name="Means of transport">
</div>
<div class="VesselNo"><label for="">Vessel number</label><input ng-focus-model type="text" name="Vessel number">
</div>
<div class="LoadingPort"><label for="">Loading port</label><input ng-focus-model type="text" name="Loading port">
</div>
<div class="DischargePort"><label for="">Discharge port</label><input ng-focus-model type="text" name="Discharge port">
</div>
-->
<div class="DeliveryPlace"><label for="delivery_place">Delivery place</label>
<textarea ng-focus-model rows="3" type="text" name="delivery_place" disabled>
{{$ctrl.trade.adata.shipments[0].destination.address.formatted_address}} {{$ctrl.trade.adata.shipments[0].destination.address.name}}
</textarea>
</div>
<div class="bt ExtraInfo">
<label for="extra_info">
<!-- <span class="noprint">Extra transport details</span> -->
<span class="noprint" ng-if="$ctrl.trade.adata.shipments[0].additional_transport_info">Extra transport details</span>
</label>
<textarea ng-focus-model rows="3" type="text" name="extra_info" ng-model="$ctrl.trade.adata.shipments[0].additional_transport_info"></textarea>
</div>
</div>
<div class="bt rt Payment">
<div class="bt rt PaymentTerms"><label for="payment_terms">Payment &amp; delivery terms</label>
<textarea ng-focus-model type="text" name="payment_terms" ng-model="$ctrl.trade.adata.invoices[0].terms_full_text"></textarea>
</div>
<div class="bt PaymentCurrency"><label for="payment_currency">Payment currency</label>
<input ng-focus-model type="text" name="payment_currency" ng-model="$ctrl.trade.adata.invoices[0].currency">
</div>
<div class=" SellerBank">
<label for="seller_bank">
<span class="noprint">Seller's bank</span>
<span ng-if="$ctrl.trade.adata.invoices[0].payment_options=='lc'">Seller's bank</span>
</label>
<textarea ng-focus-model type="text" name="seller_bank"></textarea>
</div>
</div>
<div class="lt rt bt Shipping">
<div class="rt ShippingMarks"><label for="shipping_marks">Shipping marks</label>
<textarea ng-focus-model type="text" name="shipping_marks" ng-model="$ctrl.trade.adata.shipments[0].shipping_marks">
</textarea>
</div>
<div class=" rt PackagesDescription"><label for="goods_description">No. and kind of packages; description
of goods</label>
<textarea ng-focus-model type="text" name="goods_description" ng-model="$ctrl.trade.adata.shipments[0].description">
</textarea>
</div>
<div class="Dimensions">
<div class="bt rt GrossWt"><label for="gross_wt">Total gross wt (kg)</label>
<input ng-focus-model fcsa-number type="text" name="gross_wt" ng-model="$ctrl.trade.adata.shipments[0].gross_weight">
</div>
<div class="bt NetWt"><label for="net_wt">Total net wt (kg) </label>
<input ng-focus-model fcsa-number type="text" name="net_wt" ng-model="$ctrl.trade.adata.shipments[0].net_weight">
</div>
<div class="rt GrossVol"><label for="gross_vol">Total cube (m3)</label>
<input ng-focus-model fcsa-number type="text" name="gross_vol" ng-model="$ctrl.trade.adata.shipments[0].volume">
</div>
</div>
</div>
<div item-overflow style="vertical-align: top" class="lt rt bt Items" >
<table style="table-layout:fixed;">
<tr class="ItemsHeadings">
<td class="rt">
#
</td>
<td class="rt">
Description
</td>
<td class="rt">
Commodity Code
</td>
<td class="rt" >
Quantity
</td>
<td class="rt" >
Unit price
</td>
<td>
Amount
</td>
</tr>
<tr ng-repeat="d in $ctrl.trade.adata.shipments[0].items">
<td class="rt" style="width:5%">
{{$index+1}}
</td>
<td class="rt" style="width:43%">
<!-- <textarea type="text" name="item_description" ng-model="d.description"></textarea> -->
<div class="ItemRow" contenteditable ng-blur="$ctrl.resetScrollToTop($event)" ng-model="d.description">
{{d.description}}</div>
<!-- Note - in my implemenation I don't need to have {{}} to populate this field -->
</td>
<td class="rt" style="width:13%">
<!-- <textarea type="text" name="item_description" ng-model="d.HS_code.Code"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.HS_code.Code">{{d.HS_code.Code}}</div>
</td>
<td class="rt" style="width:10%">
<!-- <textarea type="text" name="item_description" ng-model="d.quantity"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.quantity">{{d.quantity}}</div>
</td>
<td class="rt" style="width:10%">
<!-- <textarea type="text" name="item_description" ng-model="d.unit_price"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.unit_price">{{d.unit_price}}</div>
</td>
<td class="rt" style="width:10%">
<!-- <textarea type="text" name="item_description" ng-model="d.amount"></textarea> -->
<div class="ItemRow" contenteditable ng-model="d.amount">{{d.amount}}</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="lt bt rt Subtotals">
<div class="lt bt Subtotal"><label for="subtotal">Subtotal</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="subtotal" ng-model="$ctrl.trade.adata.invoices[0].subtotal">
</div>
<div class=" lt bt Charges"><label for="charges">Total charges</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="charges" ng-model="$ctrl.trade.adata.invoices[0].charges">
</div>
<div class=" lt Deductions"><label for="deductions">Total deductions</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="deductions" ng-model="$ctrl.trade.adata.invoices[0].discounts">
</div>
</div>
<div class="lt bt rt Clauses"><label for="clauses_notes">Clauses and/or Notes
</label>
<textarea ng-focus-model type="text" name="clauses_notes" ng-model="$ctrl.trade.adata.invoices[0].clauses_notes">
</textarea>
</div>
<div class="bt rt SummarySign">
<div class="bt Totals"><label for="total_to_pay">Total to pay</label>
<input ng-focus-model fcsa-number class="number-right" type="text" name="total_to_pay" ng-model="$ctrl.trade.adata.invoices[0].amount">
</div>
<div class="bt TotalsWords"><label for="total_to_pay_words">Total to pay (in words)</label>
<textarea ng-focus-model style="text-transform:capitalize" name="total_to_pay_words" ng-model="$ctrl.trade.adata.invoices[0].total_words"></textarea>
</div>
<div class="bt box SignatureName"><label for="signatory_name">Name of signatory</label>
<input ng-focus-model type="text" name="signatory_name" ng-model="$ctrl.trade.adata.invoices[0].signatory">
</div>
<div class="bt box PlaceDate"><label for="sig_place_date">Place and date</label>
<input ng-focus-model type="text" name="sig_place_date" ng-model="$ctrl.trade.adata.invoices[0].sig_place_date">
</div>
<div class=" box Signature"><label for="inv_signature">Signature</label>
<input ng-focus-model type="text" name="inv_signature" ng-model="$ctrl.trade.adata.invoice[0].signature">
<!-- blob/image, or else digital signature -->
</div>
</div>
</div>
</div>
<div class="noprint col-md-3">
</div>
</div>
var app = angular.module("app", []);
angular.module("app", []).controller("LayoutViewController", function($http, $compile, $scope) {
var allDescendants = function(node, html) {
for (var i = 0; i < node.length; i++) {
var child = node[i];
allDescendants(child, html);
// html += $compile( $(child).html())($scope)
html += $(child).html()
console.log(html);
}
}
this.focus = focus;
this.genAPI2PDF = function() {
var filename = "test.dpf"
if (!filename) filename = "doc" + uuid() + '.pdf';
return new Promise(function (resolve, reject) {
// this line no longer works in Chrome.
var elements = document.getElementsByClassName('a4');
var pages = [];
angular.forEach(elements, function (element) {
pages.push(element);
});
// var page_html = getElementChildrenAndStyles(pages);
$http.defaults.headers.common.Authorization = '5aa91bad-dcc8-4a18-9116-afc25e4fb4cc'; //replace with our API key from portal.api2pdf.com
var endpoint = "https://v2018.api2pdf.com/chrome/html"
var html = $(pages).html();
var compiled_html = $compile(html)($scope);
var total_html = '';
console.log(compiled_html)
//allDescendants($(pages[0]).children(), total_html);
//console.log(total_html);
// var compiled_html = $compile(html)($scope);
// var i = 0;
// angular.forEach(html, function (node) {
// // i++
// total_html += $(node).html()
// });
// var compiled_html = $compile($(total_html).html())($scope);
// console.log(compiled_html);
var payload = {
html: total_html , //set your HTML here!
inlinePdf: true,
}
// $http.post(endpoint, payload).then(
// function(response) {
// // console.log(response) //your PDF is in this response. Do something with it!
// window.open(response.data.pdf);
// },
// function(error) {
// });
}
)}
this.genPDF2 = function() {
// this line no longer works in Chrome
var elements = document.getElementsByClassName('a4');
var pages = [];
angular.forEach(elements, function (element) {
pages.push(element);
});
// #49 sometimes it taking a long time to generate pdf
// workaround before server side solution is to have a fa-spinner waiting helper
// quick fix for setting margins until pdf_target calss is aligned to A4
var margins;
if ($(pages[0]).hasClass('a4')) {
margins = [ 0, 0, -25, 0];
} else {
margins = [ 0, -5, -25, 0]; //#189 test all the margins - better to parameterise based on received padding of the target class
}
var orientation = 'portrait';
if($(pages[0]).hasClass('landscape'))
orientation = 'landscape';
var opt = {
// margin: 10,
margin: margins, // throws an error if the margins plus the page size from index.css overflow
filename: 'TEST.PDF',
image: { type: 'jpeg', quality: 0.5 },
html2canvas: { scale: 4 },
jsPDF: { unit: 'mm', format: 'a4', orientation: orientation }
};
var binaryFile;
var worker = html2pdf().set(opt).from(pages[0]).toPdf();
pages.slice(1).forEach(function (page) {
var orientation;
if($(page).hasClass('landscape')) {
orientation = 'landscape';
} else {
orientation = 'portrait';
}
worker = worker.get('pdf').then(function (pdf) {
pdf.addPage('a4', orientation );
}).from(page).toContainer().toCanvas().toPdf();
});
worker = worker.outputPdf('datauristring')
.then(function (file) {
binaryFile = file.replace('data:application/pdf;base64,', '');
})
.save()
.then(function () {
return resolve({ binaryPdf: binaryFile, fileName: filename });
})
.catch(reject);
}
// for view variables
this.view = {
issue_date: true,
po_date:false,
focus_field: focus.focus_field
};
this.item_row_height = '40px';
// after function
this.adjustRows = function() {
this.item_row_height = "max-content";
}
// wpx - to globalise for all components
// Current defined in itef-v2.js.
this.dateOptions = {
formatYear : 'yy',
startingDay : 1,
dateFormat: 'dd-MM-yyyy'
};
var trade = {};
trade = txdata;
// trade comes throught with fldPayment - to be removed and shipments[] (in array form) already
// then we get a loaded transaction (which has already been saved and loaded from the db and re-read into adata)
trade.adata = JSON.parse(trade.fldTradeData);
// simplification: assume dutiable value is equal to contract price
trade.adata.shipments[0].destination.dutiable_value = trade.adata.contract.contract_price;
// TODO: decide if invoices (and shipments) are array or object
trade.adata.invoices[0].currency = trade.adata.contract.contract_ccy;
trade.adata.invoices[0].subtotal = trade.adata.contract.subtotal;
trade.adata.invoices[0].charges = trade.adata.contract.charges + trade.adata.contract.sales_tax;
trade.adata.invoices[0].discounts = trade.adata.contract.discount;
trade.adata.invoices[0].amount = trade.adata.contract.contract_price;
// let pmts = JSON.parse(trade.fldPayments);
// for (var pmtobj in pmts) {
// trade.adata.invoices.push(pmts[pmtobj]);
// };
trade.adata.invoices[0].charges = Math.floor(trade.adata.invoices[0].charges * 100) / 100;
trade.adata.invoices[0].discounts = Math.floor(trade.adata.invoices[0].discounts * 100) / 100;
trade.adata.invoices[0].amount = Math.floor(trade.adata.invoices[0].amount * 100) / 100;
// trade.adata.invoices[0].total_words = currencyToEnglish(trade.adata.invoices[0].amount, trade.adata.invoices[0].currency);
// Payment details wording
if (angular.isUndefined(trade.adata.invoices[0].payment_terms)) {
trade.adata.invoices[0].payment_terms = 'XX';
}
trade.adata.invoices[0].terms_full_text =
'Net ' + trade.adata.invoices[0].payment_terms +
' days of invoice on delivery Incoterms 2010 ' +
trade.adata.shipments[0].incoterm.code + ' ' +
trade.adata.shipments[0].incoterm.PointType;
// Packages and goods description wording
trade.adata.shipments[0].description =
trade.adata.shipments[0].quantity +
' package' + ((trade.adata.shipments[0].quantity === 1) ? "" : "s in total") +
' for contract ' + trade.adata.contract.description;
// Origin and destination wording
// simplification: assume one common country of origin for all goods in invoice
// simplification: assume country of origin is seller's country of REGISTRATION
if ((trade.adata.shipments[0].origin.address.country_code != '') &&
(trade.adata.shipments[0].origin.country.alpha_2 == '')) {
trade.adata.shipments[0].origin.country.code =
trade.adata.shipments[0].origin.address.country_code; // alpha_2
};
// trade.adata.shipments[0].origin.country = $filter('getCountryByAlpha')(tbServices.service('country').src(), trade.adata.shipments[0].origin.country.code);
trade.adata.shipments[0].origin_country_text = trade.adata.shipments[0].origin.country.name;
// simplification: assume one common country of destination for all goods in invoice
// simplification: assume country of destination is buyer's country of REGISTRATION
if ((trade.adata.shipments[0].destination.address.country_code != '') &&
(trade.adata.shipments[0].destination.country.alpha_2 == '')) {
trade.adata.shipments[0].destination.country = {};
trade.adata.shipments[0].destination.country.code =
trade.adata.shipments[0].destination.address.country_code; // alpha_2
};
// trade.adata.shipments[0].destination.country = $filter('getCountryByAlpha')(tbServices.service('country').src(), trade.adata.shipments[0].destination.country.code);
trade.adata.shipments[0].destination_country_text = trade.adata.shipments[0].destination.country.name;
// seller
var seller = trade.fldSellerName; // trade.adata.contract.seller; FIX: contract.seller does not exist, temporary workaround
var seller_and_address = seller.organisation + "\n"
+ seller.tradingAddress1 + "\n"
+ seller.tradingAddress2 + "\n"
+ seller.tradingCounty + "\n"
+ seller.tradingPostcode + "\n"
+ seller.fldCountry;
trade.adata.invoices[0].seller_and_address = seller_and_address;
// buyer
var buyer = trade.adata.contract.buyer;
var buyer_and_address = buyer.organisation + "\n"
+ buyer.tradingAddress1 + "\n"
+ buyer.tradingAddress2 + "\n"
+ buyer.tradingCounty + "\n"
+ buyer.tradingPostcode + "\n"
+ buyer.fldCountry;
trade.adata.invoices[0].buyer_and_address = buyer_and_address;
// simplification: consginee set to buyer
trade.adata.shipments[0].consignee_and_address = buyer_and_address;
this.rowNumber = function ($index) { var row = $index + 1; return { 'grid-row': row }; };
this.toNumber = function () { return parseInt(elem.fc) + parseInt(elem.cpc); };
this.validate = function () {
console.log("validating")
trade.adata.checks = [];
if (trade.adata.invoices[0].seller_and_address.search("\n\n") > 0) {
trade.adata.checks.push({
"comment": "Seller details incomplete",
"fields": ["fldSeller"],
"priority": "error",
"rank": 1
});
}
if (trade.adata.shipments[0].consignee_and_address.search("\n\n") > 0) {
trade.adata.checks.push({
"comment": "Consignee details incomplete",
"fields": ["fldConsignee"],
"priority": "error",
"rank": 1
});
}
if (trade.adata.invoices[0].buyer_and_address.search("\n\n") > 0) {
trade.adata.checks.push({
"comment": "Buyer details incomplete",
"fields": ["fldBuyer"],
"priority": "error",
"rank": 1
});
}
var headers = { 'Content-Type': 'application/json' };
var txpostdata = {
'data': trade.adata,
'document': 'invoice'
};
var config = {};
var apiEndpoint = "http://pyanywh.ddns.net";
// var apiEndpoint = "http://127.0.0.1:50040";
$http.post(apiEndpoint + '/v1/validate', txpostdata, headers, config).then(
function (response) {
for (i = 0; i < response.data.data.length; i++) {
trade.adata.checks.push(response.data.data[i])
}
});
// trade.adata.invoices[0].total_words = this.num2words(trade.adata.invoices[0].amount, trade.adata.invoices[0].currency);
};
/* TEMPORARY SAVE TRANSACTION */
var saveTransaction = function() {
trade.fldTradeData = JSON.stringify(trade.adata);
var postdata = {};
postdata.transaction = trade;
$http({
method: 'POST',
url: '/save_transaction.php',
data: postdata,
headers: { 'Content-Type': 'application/json' },
}).then(
function successCallback(response) {
var msgobj = { status: "success", message: "Order saved" };
},
function errorCallback(response) {
console.error("error saving update to existing transaction" + response);
}
);
}
var timeout = null;
var debounceSaveUpdates = function(newVal, oldVal) {
if (newVal != oldVal) {
if (timeout) {
$timeout.cancel(timeout)
}
timeout = $timeout(saveTransaction, 2000); // 1000 = 1 second
console.log("running autosave")
}
};
// $scope.$watch( '$ctrl.trade.adata', debounceSaveUpdates, true);
// var scrollElement = "#ItemSection";
// $scope.$watch(function() { return angular.element(scrollElement).is(':visible') }, function() {
// scrollTo(scrollElement);
// });
this.resetScrollToTop=function (event) {
//
//angular.element(element)[0].scrollTop = 0;
// debugger
//alert("here");
var element = event.target;
var itemElement = element.offsetParent;
itemElement.scrollTop = 0;
}
this.num2words = function(num, ccy) {
var headers = { 'Content-Type' : 'application/json' };
var config = {};
var apiEndpoint = "http://pyanywh.ddns.net";
// var apiEndpoint = "http://127.0.0.1:50040";
$http.post(apiEndpoint + '/v1/towords', {'data': {'number': num, 'currency': ccy}}, headers, config).then(
function(response) {
trade.adata.invoices[0].total_words = response.data.words;
});
};
this.trade = trade;
});
app.directive('ngFocusModel', function () {
return function (scope, element) {
var focusListener = function () {
scope.hasFocus = true;
scope.hasNameFocus = element[0].name;
scope.$digest();
};
var blurListener = function () {
scope.hasFocus = false;
scope.hasNameFocus = '';
scope.$digest();
};
element[0].addEventListener('focus', focusListener, true);
element[0].addEventListener('blur', blurListener, true);
};
});
// wpfix - following function is working in firefox, not chrome
app.directive('itemOverflow', function () {
return function (scope, element) {
var overflowListener = function () {
scope.hasOverflowed = true;
scope.$digest();
};
var underflowListener = function () {
scope.hasOverflowed = false;
scope.$digest();
};
element[0].addEventListener('overflow', overflowListener, false);
element[0].addEventListener('underflow', underflowListener, false);
element[0].addEventListener('overflowchanged', overflowListener, false);
};
});
app.directive('eventFocus', function(focus) {
return function(scope, elem, attr) {
elem.on(attr.eventFocus, function() {
console.log(attr.name);
focus(attr.name);
});
// Removes bound events in the element itself
// when the scope is destroyed
scope.$on('$destroy', function() {
elem.off(attr.eventFocus);
});
};
});
app.factory('focus', function($timeout, $window) {
return function(id) {
// timeout makes sure that it is invoked after any other event has been triggered.
// e.g. click events that need to run before the focus or
// inputs elements that are in a disabled state but are enabled when those events
// are triggered.
this.focus_field = id;
$timeout(function() {
var element = $window.document.getElementById(id);
if(element)
element.focus();
});
};
});
app.directive("contenteditable", function() {
return {
restrict: "A",
require: "ngModel",
link: function(scope, element, attrs, ngModel) {
function read() {
//ngModel.$setViewValue(element.html());
var text = element[0].innerText;
ngModel.$setViewValue(text);
}
ngModel.$render = function() {
if (!ngModel.$viewValue) { element[0].innerText = ""; }
else {
element[0].innerText = ngModel.$viewValue;
}
};
element.bind("blur keyup change", function() {
scope.$apply(read);
});
}
};
});
var txdata = {"txid":854,"fldSellerid":365,"fldSellerName":"PARKWAY LOGIC LTD.","fldSellerCountryid":185,"fldSellerCountry":"United Kingdom","fldBuyerid":573,"fldBuyerName":"GM Holden Ltd.","fldBuyerCountryid":9,"fldBuyerCountry":"Australia","fldContractCcy":"USD","fldUpdated":"2019-02-13 12:13:46","fldFinalDestination":"","fldRepayDate":"2020-01-31","fldMaxFin":0,"fldFinCost":0,"fldDocCost":0,"fldValue":0,"fldTotal":5000,"fldDescription":"","fldCreated":"2019-02-01 20:20:03","fldIncoTerms":"","fldGoodsCode":"","fldGoodsDescription":"","fldStatus":"New","fldPurchaseOrder":"","fldInvoiceNumber":"","fldInvoiceApproval":"","fldCreatedBy":298,"fldFXConversionEstDate":"","fldFXProduct":"","fldFXHedgeAmount":0,"fldFXRequiresAccountNo":"","fldFXCustomerNumber":"","fldFXRequiresAuthSig":"","fldFXAuthorisedSign":"","fldFXRequiresInvIssDt":"","fldFXInvIssueDate":"","fldFXRequiresPmtDeadline":"","fldFXPayDeadline":"","fldFXRequiresCI":"","fldCITenor":"","fldCIAmount":0,"fldCILossPayee":"","fldFXRequiresTransIns":"","fldTILossPayee":"","fldFXRequiresExpLic":"","fldDXExportLicense":"","fldTRIndirectExport":"tellme","fldTRExitCountry":"","fldTRSingleTransportContract":"","fldTRTransportTo":"","fldTRInsureCargoTo":"","fldTRInsureCargoFor":0,"fldTRTotalWeightKG":0,"fldTRTotalVolumeM3":0,"fldTRTotalPackages":0,"fldTRStackable":0,"fldTRStackableKG":0,"fldTRStackableM3":0,"fldTRStackablePackages":0,"fldTRReeferM3":0,"fldTRHazClass":"Non-hazardous","fldDXExportLicenseRequired":"","fldDXNoExportLicenceDeclaration":"","fldDXExportLicenseNumber":"","fldDXExportLicenseType":"","fldDXRequiresDutyExemption":"","fldDXExportDutyExemptionURL":"","fldDXImportDutyExemptionURL":"","fldDXRequiresCIFValue":"","fldDXShipmentCIFValue":0,"fldDXRequiresEORI":"","fldDXSellerEORI":"","fldDXRequiresAEO":"","fldDXSellerAEO":"","fldDXRequiresCountryofOrigin":"","fldTRShipmentCIFValue":0,"fldDXCountryofOrigin":"826","fldFutureInvoice":"","fldCISector":"","fldCIBadDebts":0,"fldCIROT":0,"fldCIAllMonies":"","fldCIWIPRequired":"0","fldCIWIPPct":0,"fldTRurgency":"","fldTRPickupFacilities":"Plain","fldTRPackageType":"","fldTRInsuranceLevel":"","fldTRMovementCert":"","fldPmtMethodKnown":"","fldTRTriage":"","fldFIOutsourcedCollection":"","fldKnowDates":"","fldFIPreship":"","fldDXCountryofOrigin":"826","fldDXFinalUseCountry":"36","fldTRDropOffAddress":"","fldTRDropOffCountry":"AU","fldTRPickupAddress":"","fldTRPickupCountry":"GB","fldIncotermReceiving":0,"fldIncotermModifier":"","fldGanttData":"[{\"id\":\"milestones\",\"name\":\"Milestones\",\"height\":\"2em\",\"color\":\"#F1C232\",\"tasks\":[{\"id\":\"milestone-invoice\",\"name\":\"Invoice\",\"from\":\"2019-02-01T00:00:00.000Z\",\"to\":\"2019-02-02T00:00:00.000Z\",\"content\":\"<i class=\\\"fa fa-star\\\"><\/i> {{task.model.name}}\",\"color\":\"transparent\",\"movable\":{\"allowResizing\":false,\"allowRowSwitching\":false}},{\"id\":\"milestone-payment\",\"name\":\"Payment\",\"from\":\"2019-02-01T00:00:00.000Z\",\"to\":\"2019-02-02T00:00:00.000Z\",\"content\":\"<i class=\\\"fa fa-star\\\"><\/i> {{task.model.name}}\",\"color\":\"transparent\",\"movable\":{\"allowResizing\":false,\"allowRowSwitching\":false}},{\"id\":\"milestone-purchase\",\"name\":\"Purchase\",\"from\":\"2019-02-01T00:00:00.000Z\",\"to\":\"2019-02-02T00:00:00.000Z\",\"content\":\"<i class=\\\"fa fa-star\\\"><\/i> {{task.model.name}}\",\"color\":\"transparent\",\"movable\":{\"allowResizing\":false,\"allowRowSwitching\":false}},{\"id\":\"milestone-delivery\",\"name\":\"Delivery\",\"from\":\"2019-02-01T00:00:00.000Z\",\"to\":\"2019-02-02T00:00:00.000Z\",\"content\":\"<i class=\\\"fa fa-star\\\"><\/i> {{task.model.name}}\",\"color\":\"transparent\",\"movable\":{\"allowResizing\":false,\"allowRowSwitching\":false}}]},{\"name\":\"Milestones\",\"id\":\"fi-milestones\",\"height\":\"2em\",\"color\":\"rgb(162, 210, 241)\"},{\"id\":\"fi\",\"name\":\"fi\",\"content\":\"<i class=\\\"fa fa-dollar\\\" ng-click=\\\"scope.handleRowIconClick(row.model)\\\"><\/i> Financing\",\"height\":\"1.4em\"},{\"parent\":\"fi\",\"id\":\"fi-steps\",\"name\":\"steps\",\"tasks\":[{\"name\":\"Initiation\",\"from\":\"2019-02-13T12:12:20.877Z\",\"to\":\"2019-02-16T12:12:20.877Z\",\"id\":\"fi-initiation\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Planning\",\"from\":\"2019-02-16T12:12:20.877Z\",\"to\":\"2019-02-26T12:12:20.877Z\",\"id\":\"fi-planning\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Acceptance\",\"from\":\"2019-02-26T12:12:20.877Z\",\"to\":\"2019-03-01T12:12:20.877Z\",\"id\":\"fi-acceptance\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Fulfillment\",\"from\":\"2019-03-01T12:12:20.877Z\",\"to\":\"2019-03-01T12:12:20.877Z\",\"id\":\"fi-fulfillment\",\"movable\":false,\"classes\":\"milestone-task\"}]},{\"name\":\"Milestones\",\"id\":\"dx-milestones\",\"height\":\"2em\",\"color\":\"rgb(162, 210, 241)\"},{\"id\":\"dx\",\"name\":\"dx\",\"content\":\"<i class=\\\"fa fa-globe\\\" ng-click=\\\"scope.handleRowIconClick(row.model)\\\"><\/i> Customs\",\"height\":\"1.4em\"},{\"parent\":\"dx\",\"id\":\"dx-steps\",\"name\":\"steps\",\"tasks\":[{\"name\":\"Initiation\",\"from\":\"2019-02-04T14:17:26.877Z\",\"to\":\"2019-02-13T12:12:20.877Z\",\"id\":\"dx-initiation\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Planning\",\"from\":\"2019-02-13T12:12:20.877Z\",\"to\":\"2019-02-23T12:12:20.877Z\",\"id\":\"dx-planning\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Acceptance\",\"from\":\"2019-02-23T12:12:20.877Z\",\"to\":\"2019-02-26T12:12:20.877Z\",\"id\":\"dx-acceptance\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Fulfillment\",\"from\":\"2019-02-26T12:12:20.877Z\",\"to\":\"2019-02-26T12:12:20.877Z\",\"id\":\"dx-fulfillment\",\"movable\":false,\"classes\":\"milestone-task\"}]},{\"name\":\"Milestones\",\"id\":\"fx-milestones\",\"height\":\"2em\",\"color\":\"rgb(162, 210, 241)\"},{\"id\":\"fx\",\"name\":\"fx\",\"content\":\"<i class=\\\"fa fa-exchange\\\" ng-click=\\\"scope.handleRowIconClick(row.model)\\\"><\/i> Foreign exchange\",\"height\":\"1.4em\"},{\"parent\":\"fx\",\"id\":\"fx-steps\",\"name\":\"steps\",\"tasks\":[{\"name\":\"Initiation\",\"from\":\"2019-02-13T12:12:20.878Z\",\"to\":\"2019-02-16T12:12:20.878Z\",\"id\":\"fx-initiation\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Planning\",\"from\":\"2019-02-16T12:12:20.878Z\",\"to\":\"2019-02-26T12:12:20.878Z\",\"id\":\"fx-planning\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Acceptance\",\"from\":\"2019-02-26T12:12:20.878Z\",\"to\":\"2019-03-01T12:12:20.878Z\",\"id\":\"fx-acceptance\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Fulfillment\",\"from\":\"2019-03-01T12:12:20.878Z\",\"to\":\"2019-03-01T12:12:20.878Z\",\"id\":\"fx-fulfillment\",\"movable\":false,\"classes\":\"milestone-task\"}]},{\"name\":\"Milestones\",\"id\":\"tr-milestones\",\"height\":\"2em\",\"color\":\"rgb(162, 210, 241)\",\"tasks\":[{\"id\":\"tr-milestone-ship\",\"name\":\"Ship date\",\"content\":\"<i class=\\\"fa fa-star\\\"><\/i> {{task.model.name}}\",\"color\":\"transparent\",\"from\":\"2019-02-01T00:00:00.000Z\",\"to\":\"2019-02-02T00:00:00.000Z\",\"movable\":false}]},{\"id\":\"tr\",\"name\":\"tr\",\"content\":\"<i class=\\\"fa fa-truck\\\" ng-click=\\\"scope.handleRowIconClick(row.model)\\\"><\/i> Transport\",\"height\":\"1.4em\"},{\"parent\":\"tr\",\"id\":\"tr-steps\",\"name\":\"steps\",\"tasks\":[{\"name\":\"Initiation\",\"from\":\"2019-02-04T14:17:26.878Z\",\"to\":\"2019-02-13T12:12:20.878Z\",\"id\":\"tr-initiation\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Planning\",\"from\":\"2019-02-13T12:12:20.878Z\",\"to\":\"2019-02-23T12:12:20.878Z\",\"id\":\"tr-planning\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Acceptance\",\"from\":\"2019-02-23T12:12:20.878Z\",\"to\":\"2019-02-26T12:12:20.878Z\",\"id\":\"tr-acceptance\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Fulfillment\",\"from\":\"2019-02-26T12:12:20.878Z\",\"to\":\"2019-02-01T00:00:00.000Z\",\"id\":\"tr-fulfillment\",\"movable\":false,\"classes\":\"milestone-task\"}]},{\"name\":\"Milestones\",\"id\":\"ct-milestones\",\"height\":\"2em\",\"color\":\"rgb(162, 210, 241)\"},{\"id\":\"ct\",\"name\":\"ct\",\"content\":\"<i class=\\\"fa fa-certificate\\\" ng-click=\\\"scope.handleRowIconClick(row.model)\\\"><\/i> Certification\",\"height\":\"1.4em\"},{\"parent\":\"ct\",\"id\":\"ct-steps\",\"name\":\"steps\",\"tasks\":[{\"name\":\"Initiation\",\"from\":\"2019-02-13T12:12:20.878Z\",\"to\":\"2019-02-16T12:12:20.878Z\",\"id\":\"ct-initiation\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Planning\",\"from\":\"2019-02-16T12:12:20.878Z\",\"to\":\"2019-02-26T12:12:20.878Z\",\"id\":\"ct-planning\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Acceptance\",\"from\":\"2019-02-26T12:12:20.878Z\",\"to\":\"2019-03-01T12:12:20.878Z\",\"id\":\"ct-acceptance\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Fulfillment\",\"from\":\"2019-03-01T12:12:20.878Z\",\"to\":\"2019-03-01T12:12:20.878Z\",\"id\":\"ct-fulfillment\",\"movable\":false,\"classes\":\"milestone-task\"}]},{\"name\":\"Milestones\",\"id\":\"ci-milestones\",\"height\":\"2em\",\"color\":\"rgb(162, 210, 241)\"},{\"id\":\"ci\",\"name\":\"ci\",\"content\":\"<i class=\\\"fa fa-save\\\" ng-click=\\\"scope.handleRowIconClick(row.model)\\\"><\/i> Credit insurance\",\"height\":\"1.4em\"},{\"parent\":\"ci\",\"id\":\"ci-steps\",\"name\":\"steps\",\"tasks\":[{\"name\":\"Initiation\",\"from\":\"2019-02-13T12:12:20.878Z\",\"to\":\"2019-02-16T12:12:20.878Z\",\"id\":\"ci-initiation\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Planning\",\"from\":\"2019-02-16T12:12:20.878Z\",\"to\":\"2019-02-26T12:12:20.878Z\",\"id\":\"ci-planning\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Acceptance\",\"from\":\"2019-02-26T12:12:20.878Z\",\"to\":\"2019-03-01T12:12:20.878Z\",\"id\":\"ci-acceptance\",\"movable\":false,\"classes\":\"milestone-task\"},{\"name\":\"Fulfillment\",\"from\":\"2019-03-01T12:12:20.878Z\",\"to\":\"2019-03-01T12:12:20.878Z\",\"id\":\"ci-fulfillment\",\"movable\":false,\"classes\":\"milestone-task\"}]}]","fldPayments":"{\"0\":{\"updated\":\"\",\"updated_by\":0,\"created\":\"\",\"created_by\":0,\"assigned_to\":\"\",\"status\":\"\",\"mode\":\"\",\"name\":\"\",\"EstDate\":\"2019-02-01T00:00:00.000Z\",\"Idd\":0,\"Dwd\":0,\"pc_Rcv\":0,\"pc_Inv\":0,\"estimated_date\":\"\",\"payment_terms\":0,\"approval_staus\":\"\",\"payment_status\":\"\",\"Ied\":\"2019-02-01T00:00:00.000Z\",\"Ced\":\"2019-02-01T00:00:00.000Z\"},\"1\":{\"updated\":\"\",\"updated_by\":0,\"created\":\"\",\"created_by\":0,\"assigned_to\":\"\",\"status\":\"\",\"mode\":\"\",\"name\":\"\",\"EstDate\":\"2019-02-01T00:00:00.000Z\",\"Idd\":0,\"Dwd\":0,\"pc_Rcv\":0,\"pc_Inv\":0,\"estimated_date\":\"\",\"payment_terms\":0,\"approval_staus\":\"\",\"payment_status\":\"\",\"Ied\":\"2019-02-01T00:00:00.000Z\",\"Ced\":\"2019-02-01T00:00:00.000Z\"},\"2\":{\"updated\":\"\",\"updated_by\":0,\"created\":\"\",\"created_by\":0,\"assigned_to\":\"\",\"status\":\"\",\"mode\":\"\",\"name\":\"\",\"EstDate\":\"2019-02-01T00:00:00.000Z\",\"Idd\":0,\"Dwd\":0,\"pc_Rcv\":0,\"pc_Inv\":0,\"estimated_date\":\"\",\"payment_terms\":0,\"approval_staus\":\"\",\"payment_status\":\"\",\"Ied\":\"2019-02-01T00:00:00.000Z\",\"Ced\":\"2019-02-01T00:00:00.000Z\"},\"3\":{\"updated\":\"\",\"updated_by\":0,\"created\":\"\",\"created_by\":0,\"assigned_to\":\"\",\"status\":\"\",\"mode\":\"\",\"name\":\"\",\"EstDate\":\"2019-02-01T00:00:00.000Z\",\"Idd\":0,\"Dwd\":0,\"pc_Rcv\":0,\"pc_Inv\":0,\"estimated_date\":\"\",\"payment_terms\":0,\"approval_staus\":\"\",\"payment_status\":\"\",\"Ied\":\"2019-02-01T00:00:00.000Z\",\"Ced\":\"2019-02-01T00:00:00.000Z\"}}","fldTradeData":"{\"name\":\"\",\"shipments\":[{\"status\":\"started\",\"type\":\"courier\",\"title\":\"\",\"receiving\":[],\"origin\":{\"exporter\":\"\",\"address\":{\"address_components\":[{\"long_name\":\"196\",\"short_name\":\"196\",\"types\":[\"street_number\"]},{\"long_name\":\"Rodeo Drive\",\"short_name\":\"Rodeo Dr\",\"types\":[\"route\"]},{\"long_name\":\"Beverly Hills\",\"short_name\":\"Beverly Hills\",\"types\":[\"locality\",\"political\"]},{\"long_name\":\"Los Angeles County\",\"short_name\":\"Los Angeles County\",\"types\":[\"administrative_area_level_2\",\"political\"]},{\"long_name\":\"California\",\"short_name\":\"CA\",\"types\":[\"administrative_area_level_1\",\"political\"]},{\"long_name\":\"United States\",\"short_name\":\"US\",\"types\":[\"country\",\"political\"]},{\"long_name\":\"90212\",\"short_name\":\"90212\",\"types\":[\"postal_code\"]}],\"formatted_address\":\"196 Rodeo Dr, Beverly Hills, CA 90212, USA\",\"geometry\":{\"location\":{\"lat\":34.0650209,\"lng\":-118.4012692},\"location_type\":\"RANGE_INTERPOLATED\",\"viewport\":{\"northeast\":{\"lat\":34.0663698802915,\"lng\":-118.3999202197085},\"southwest\":{\"lat\":34.0636719197085,\"lng\":-118.4026181802915}}},\"partial_match\":true,\"place_id\":\"EioxOTYgUm9kZW8gRHIsIEJldmVybHkgSGlsbHMsIENBIDkwMjEyLCBVU0EiGxIZChQKEgnbPHNz-bvCgBHU8lIrGXgOnBDEAQ\",\"types\":[\"street_address\"],\"country_code\":\"US\",\"street_address\":\"196 Rodeo Drive \",\"locality\":\"Beverly Hills\",\"region\":\"California\",\"postal_code\":\"90212\"},\"country\":{\"name\":\"China\",\"alpha_2\":\"CN\",\"alpha_3\":\"CHN\",\"code\":\"156\"}},\"incoterm\":{\"id\":\"2\",\"code\":\"FCA\",\"Description\":\"Free Carrier (FCA)\",\"PointCountry\":\"origin\",\"PointType\":\"Seller's Premises\",\"TransportMode\":\"any\",\"DutyPayer\":\"Buyer\",\"estimates\":{\"freight\":[false,true],\"duty\":[false,true]}},\"handover\":{\"address\":{\"formatted_address\":\"\",\"country_code\":\"\"},\"country\":{\"name\":\"\",\"code\":\"\",\"alpha_2\":\"\",\"alpha_3\":\"\"}},\"destination\":{\"importer\":\"\",\"dutiable_value\":3896.16,\"address\":{\"address_components\":[{\"long_name\":\"1\",\"short_name\":\"1\",\"types\":[\"street_number\"]},{\"long_name\":\"Al Corniche Street\",\"short_name\":\"Al Corniche St\",\"types\":[\"route\"]},{\"long_name\":\"Al Dafna\",\"short_name\":\"Al Dafna\",\"types\":[\"political\",\"sublocality\",\"sublocality_level_1\"]},{\"long_name\":\"Doha\",\"short_name\":\"Doha\",\"types\":[\"locality\",\"political\"]},{\"long_name\":\"Doha\",\"short_name\":\"Doha\",\"types\":[\"administrative_area_level_1\",\"political\"]},{\"long_name\":\"Qatar\",\"short_name\":\"QA\",\"types\":[\"country\",\"political\"]}],\"formatted_address\":\"1 Al Corniche St, Doha, Qatar\",\"geometry\":{\"location\":{\"lat\":25.3184608,\"lng\":51.5294146},\"location_type\":\"ROOFTOP\",\"viewport\":{\"northeast\":{\"lat\":25.3198097802915,\"lng\":51.5307635802915},\"southwest\":{\"lat\":25.3171118197085,\"lng\":51.5280656197085}}},\"partial_match\":true,\"place_id\":\"ChIJW6mPmMbERT4Rt-mcZEbmE2Y\",\"plus_code\":{\"compound_code\":\"8G9H+9Q Doha, Qatar\",\"global_code\":\"7HQH8G9H+9Q\"},\"types\":[\"street_address\"],\"country_code\":\"QA\",\"street_address\":\"1 Al Corniche Street \",\"locality\":\"Doha\",\"region\":\"Doha\"},\"country\":{\"name\":\"France\",\"alpha_2\":\"FR\",\"alpha_3\":\"FRA\",\"code\":\"250\"}},\"mode\":{\"code\":\"FCL\",\"description\":\"Full Container Load\"},\"load_type\":{\"code\":\"container40\"},\"volume\":0.11000000000000001,\"gross_weight\":100,\"net_weight\":50,\"quantity\":1,\"quote_status\":\"1 quote\",\"quotes\":[{\"id\":0,\"comment\":\"<u>Estimates from Freightos:<\/u><br>Values includes pick up and drop off (unless stated below) with cargo insurance estimate based on full contract value.<br>Number of carriers is 3 and their codes: HLCU, MAEU, PILN.<br>Includes pickup from 196 Rodeo Dr, Beverly Hills, CA 90212, USA to USLAX Los Angeles, CA. Includes delivery from QAHMD Hamad to 1 Al Corniche St, Doha, Qatar.\",\"mode\":{\"code\":\"FCL\",\"description\":\"\"},\"cost\":{\"min\":2293,\"max\":5406},\"transit_time\":{\"min\":30,\"max\":36}}],\"items\":[{\"object_id\":1091985414,\"products\":[],\"HS_code\":{\"Code\":\"543453\",\"Description\":\"\"},\"dutiable_value\":\"\",\"dutiable_weight\":\"\",\"value\":\"\",\"duty_type\":\"\",\"duty_rate\":\"\",\"tariff_cost\":\"\",\"vtax_cost\":\"\",\"quantity\":\"5\",\"unit_cost\":75,\"markup_pc\":50,\"markup\":\"\",\"discount\":\"\",\"unit_price\":\"112.5\",\"gross_margin\":33.33,\"amount\":\"900\",\"$$hashKey\":\"object:10045\",\"description\":\"Asdkjaldjalkdsj\\nsadlkfjsajf\\nsalkfdjlsaf\\n\\n\"},{\"object_id\":1091930730,\"description\":\"asdfsadfsadf2345 3245 3245 3245\u00a0\\n\\n\\n4325 45 2345 4325 435 345 3245 325 34254325 4325 253\",\"products\":[],\"HS_code\":{\"Code\":\"\",\"Description\":\"\"},\"dutiable_value\":\"\",\"dutiable_weight\":\"\",\"value\":\"\",\"duty_type\":\"\",\"duty_rate\":\"\",\"tariff_cost\":\"\",\"vtax_cost\":\"\",\"quantity\":\"5\",\"unit_cost\":75,\"markup_pc\":50,\"markup\":\"\",\"discount\":\"\",\"unit_price\":\"112.5\",\"gross_margin\":33.33,\"amount\":\"562.5\",\"$$hashKey\":\"object:10091\"},{\"object_id\":1184204002,\"description\":\"dafsadfsad\",\"products\":[],\"HS_code\":{\"Code\":\"\",\"Description\":\"\"},\"dutiable_value\":0,\"dutiable_weight\":0,\"value\":\"\",\"duty_type\":\"\",\"duty_rate\":\"\",\"tariff_cost\":\"\",\"vtax_cost\":\"\",\"quantity\":\"1\",\"unit_cost\":413,\"markup_pc\":50,\"markup\":\"\",\"discount\":\"\",\"unit_price\":\"619.5\",\"gross_margin\":33.33333333333333,\"amount\":\"619.5\",\"$$hashKey\":\"object:3383\"},{\"object_id\":1185004643,\"description\":\"sadfasdf\\n\\nsadfsafd\",\"products\":[],\"HS_code\":{\"Code\":\"\",\"Description\":\"\"},\"dutiable_value\":0,\"dutiable_weight\":0,\"value\":\"\",\"duty_type\":\"\",\"duty_rate\":\"\",\"tariff_cost\":\"\",\"vtax_cost\":\"\",\"quantity\":\"1\",\"unit_cost\":413,\"markup_pc\":50,\"markup\":\"\",\"discount\":\"\",\"unit_price\":619.5,\"gross_margin\":33.33333333333333,\"amount\":619.5,\"$$hashKey\":\"object:3442\"},{\"object_id\":1185071013,\"products\":[],\"HS_code\":{\"Code\":\"\",\"Description\":\"\"},\"dutiable_value\":0,\"dutiable_weight\":0,\"value\":\"\",\"duty_type\":\"\",\"duty_rate\":\"\",\"tariff_cost\":\"\",\"vtax_cost\":\"\",\"quantity\":\"1\",\"unit_cost\":75,\"markup_pc\":50,\"markup\":\"\",\"discount\":\"\",\"unit_price\":112.5,\"gross_margin\":33.33333333333333,\"amount\":112.5,\"$$hashKey\":\"object:3501\",\"description\":\"lkjfljsadfl\\nsadlkfj\\nsadf\\nsadf\\n\\n\\nasdf\\nasdf\\n\\n\\n\\n\\nasdf\\n\\n\\n\\n\\nasdf\\nsdf\\nsda\\ndsf\\nfdsa\\nsfd\\n\\n\\nsadf\\nsadf\\nsdaf\\nsdf\\nsdf\\nsdf\\n\\n\\nsadfkj\"},{\"object_id\":1185955911,\"products\":[],\"HS_code\":{\"Code\":\"\",\"Description\":\"\"},\"dutiable_value\":0,\"dutiable_weight\":0,\"value\":\"\",\"duty_type\":\"\",\"duty_rate\":\"\",\"tariff_cost\":\"\",\"vtax_cost\":\"\",\"quantity\":\"1\",\"unit_cost\":413,\"markup_pc\":50,\"markup\":\"\",\"discount\":\"\",\"unit_price\":\"619.5\",\"gross_margin\":33.33333333333333,\"amount\":\"619.5\",\"$$hashKey\":\"object:3563\",\"description\":\"sadfasdfsadf\\n\\n\\ndsaf\\nfdsa\\nfds\\ndsaffdsa\\n\u00a0sadf dsafr dsaf sadf dsaf dsaf dsaf sadf\\nsadf\\n\\n\\n\\n\\nasdf\\n\\n\\ndsaf\\n\\n\\n\\n\\n\\n\\nsadf\\n\\n\\nfdsa\\n\\n\\nasdf\\n\\n\"}],\"packing_list_status\":\"not shipped\",\"packing_list_date\":\"2019-02-08T00:00:00.000Z\",\"shipped_date\":\"2019-02-15T00:00:00.000Z\",\"delivered_date\":\"2019-02-14T00:00:00.000Z\",\"packing_list_ref\":\"5445\",\"packages\":[{\"object_id\":1344097418,\"package_type\":\"\",\"products\":[],\"gross_weight\":0,\"display_gross_weight\":\"\",\"gross_volume\":0,\"display_gross_volume\":\"\",\"net_weight\":0,\"display_net_weight\":\"\",\"net_volume\":\"\",\"width\":\"\",\"height\":\"\",\"length\":\"\",\"weight_unit\":\"kg\",\"volume_unit\":\"\",\"linear_unit\":\"cm\",\"serial_number\":\"\",\"unit_of_measure\":\"\",\"unit_qty\":\"\",\"box_number\":\"\",\"quantity_of_packages\":3,\"custom_data\":{},\"$$hashKey\":\"object:1656\",\"line_gross_volume\":0,\"line_gross_weight\":0,\"line_net_weight\":0},{\"object_id\":674803129,\"package_type\":\"box\",\"products\":[],\"gross_weight\":20,\"display_gross_weight\":0,\"gross_volume\":0.025,\"display_gross_volume\":0,\"net_weight\":10,\"display_net_weight\":0,\"net_volume\":0,\"width\":9,\"height\":18,\"length\":27,\"weight_unit\":\"kg\",\"volume_unit\":\"\",\"linear_unit\":\"cm\",\"serial_number\":\"\",\"unit_qty\":null,\"box_number\":\"\",\"quantity_of_packages\":1,\"custom_data\":{},\"line_gross_volume\":0.025,\"line_gross_weight\":20,\"line_net_weight\":10,\"description\":\"ABBEVILLE'S PRIDE - box of 300 bulbs size 14\/16 - POT ASIATIC Orange-Red\",\"code\":\"ABBC42835\",\"$$hashKey\":\"object:3412\"},{\"object_id\":674712977,\"package_type\":\"box\",\"products\":[],\"gross_weight\":20,\"display_gross_weight\":0,\"gross_volume\":0.025,\"display_gross_volume\":0,\"net_weight\":10,\"display_net_weight\":0,\"net_volume\":0,\"width\":9,\"height\":18,\"length\":27,\"weight_unit\":\"kg\",\"volume_unit\":\"\",\"linear_unit\":\"cm\",\"serial_number\":\"\",\"unit_qty\":null,\"box_number\":\"\",\"quantity_of_packages\":1,\"custom_data\":{},\"line_gross_volume\":0.025,\"line_gross_weight\":20,\"line_net_weight\":10,\"description\":\"ABBEVILLE'S PRIDE - box of 300 bulbs size 14\/16 - POT ASIATIC Orange-Red\",\"code\":\"ABBC42835\",\"$$hashKey\":\"object:3471\"},{\"object_id\":673873779,\"package_type\":\"box\",\"products\":[],\"gross_weight\":40,\"display_gross_weight\":0,\"gross_volume\":0.035,\"display_gross_volume\":0,\"net_weight\":20,\"display_net_weight\":0,\"net_volume\":0,\"width\":27,\"height\":54,\"length\":108,\"weight_unit\":\"kg\",\"volume_unit\":\"\",\"linear_unit\":\"cm\",\"serial_number\":\"\",\"unit_qty\":null,\"box_number\":\"\",\"quantity_of_packages\":1,\"custom_data\":{},\"line_gross_volume\":0.035,\"line_gross_weight\":40,\"line_net_weight\":20,\"description\":\"ABBA - box of 900 bulbs size 10\/11 - Double Early Red\",\"code\":\"ABBC91799\",\"$$hashKey\":\"object:3533\"},{\"object_id\":673700864,\"package_type\":\"box\",\"products\":[],\"gross_weight\":20,\"display_gross_weight\":0,\"gross_volume\":0.025,\"display_gross_volume\":0,\"net_weight\":10,\"display_net_weight\":0,\"net_volume\":0,\"width\":9,\"height\":18,\"length\":27,\"weight_unit\":\"kg\",\"volume_unit\":\"\",\"linear_unit\":\"cm\",\"serial_number\":\"\",\"unit_qty\":null,\"box_number\":\"\",\"quantity_of_packages\":1,\"custom_data\":{},\"line_gross_volume\":0.025,\"line_gross_weight\":20,\"line_net_weight\":10,\"description\":\"ABBEVILLE'S PRIDE - box of 300 bulbs size 14\/16 - POT ASIATIC Orange-Red\",\"code\":\"ABBC42835\",\"$$hashKey\":\"object:3595\"}],\"products\":[{\"object_id\":1974320057,\"product_id\":\"11602\",\"item_id\":1091985414,\"package_id\":1344097418,\"$$hashKey\":\"object:1625\"},{\"object_id\":830917566,\"product_id\":\"11260\",\"item_id\":1184204002,\"package_id\":674803129},{\"object_id\":830827414,\"product_id\":\"11260\",\"item_id\":1185004643,\"package_id\":674712977},{\"object_id\":43651140,\"product_id\":\"11602\",\"item_id\":1185071013,\"package_id\":673873779},{\"object_id\":829815301,\"product_id\":\"11260\",\"item_id\":1185955911,\"package_id\":673700864}],\"$$hashKey\":\"object:625\",\"description\":\"1 package for contract 90 boxes as per packing list\",\"consignee_and_address\":\"SCANTECH SERVICES\\n50 SERANGOON NORTH AVENUE 4,\\n#07-05\\nFIRST CE\\n555856\\nSingapore\",\"origin_country_text\":\"China\",\"destination_country_text\":\"France\",\"shipping_marks\":\"As many shipping marks as are required\",\"additional_transport_info\":\"Extra transport details are entered into here\"}],\"invoices\":[{\"updated\":\"\",\"updatedby\":0,\"created\":\"\",\"createdby\":0,\"status\":\"draft\",\"reference\":\"\",\"invoice_ref\":\"\",\"signatory\":\"Chris Woodington\",\"invoice_contact\":{\"name\":\"\",\"email\":\"\"},\"approval_staus\":\"\",\"payment_options\":\"gw\",\"currency\":\"USD\",\"subtotal\":3433.5,\"charges\":1149.36,\"sales_tax\":0,\"discounts\":686.7,\"amount\":3896.16,\"balance_due\":0,\"payment_terms\":33,\"due_date\":\"28-03-2019\",\"clauses_notes\":\"Bank details:\\nIBAN 39302-31231-39193-3918392\\n\\nAuthentication.php - all the PurchaseOrder endpoints \\n(ideally move to a separate file)\\nPurchaseorder.service.js - factory\/service for accessing endpoints\\nTransaction.itembuilder.component.js - functions for the purchase order column on the item tab\\nTransaction.purchaseorder.component.js - fucntions for the related purchase order tab\\n45645652355\",\"terms_conditons\":\"\",\"seller_and_address\":\"undefined\\nundefined\\nundefined\\nundefined\\nundefined\\nundefined\",\"buyer_and_address\":\"SCANTECH SERVICES\\n50 SERANGOON NORTH AVENUE 4,\\n#07-05\\nFIRST CE\\n555856\\nSingapore\",\"origin_country_text\":\"\",\"destination_country_text\":\"\",\"shipping_marks\":\"\",\"invoice_date\":\"2019-02-01T20:19:25.894Z\",\"$$hashKey\":\"object:953\",\"total_words\":\"three thousand eight hundred and eighty US Dollars and and sixteen cents\",\"terms_full_text\":\"Net 33 days of invoice on delivery Incoterms 2010 FCA Seller's Premises\",\"invoice_number\":\"INV93012-a\",\"contact\":\"Joe Smith\",\"issue_date\":\"2019-02-22T00:00:00.000Z\",\"additional_info\":\"Extra details - we don't ask questions.\\nasdf\\nsadf\\nsadf\\nsdaf\"}],\"payments\":[],\"contract\":{\"object_id\":0,\"description\":\"90 boxes as per packing list\",\"buyer_ref\":\"5434534\",\"seller_ref\":\"789789\",\"buy_sell\":\"\",\"sign_date\":\"2019-02-16T00:00:00.000Z\",\"contract_ccy\":\"USD\",\"seller\":{\"orgid\":522,\"organisation\":\"SCANTECH SERVICES\",\"contactName\":\"\",\"operationcountry\":\"157\",\"fldCountry\":\"Singapore\",\"startedSince\":\"\",\"relationorgid\":\"365\",\"sellerNameLinkedTo\":\"PARKWAY LOGIC LTD.\",\"email\":\"\",\"phone\":\"\",\"fldCreated\":\"2018-02-05 12:31:08\",\"fldUpdated\":\"2018-02-05 12:31:08\",\"createdBy\":298,\"updatedBy\":298,\"avgInvoice\":\"\",\"avgPaydays\":\"\",\"percentRev\":\"\",\"companyRegNum\":\"53313334C\",\"fldLEI\":\"No LEI found in SG\",\"fldLEIUpdated\":\"2018-02-05 12:31:00\",\"fldOpenCorpUpdated\":\"2016-12-02 19:44:41\",\"registeredAddress1\":\"50 SERANGOON NORTH AVENUE 4, #07-05, FIRST CENTRE, SINGAPORE(555856)\",\"registeredAddress2\":\"\",\"registeredCounty\":\"\",\"registeredPostcode\":\"\",\"tradingAddressFull\":\"\",\"tradingCountry\":\"\",\"tradingAddress1\":\"50 SERANGOON NORTH AVENUE 4, #07-05, FIRST CE\",\"tradingAddress2\":\"\",\"tradingCounty\":\"\",\"tradingPostcode\":\"\"},\"buyer\":{\"orgid\":522,\"organisation\":\"SCANTECH SERVICES\",\"contactName\":\"Joe Smith\",\"operationcountry\":\"157\",\"fldCountry\":\"Singapore\",\"startedSince\":\"\",\"relationorgid\":\"365\",\"sellerNameLinkedTo\":\"PARKWAY LOGIC LTD.\",\"email\":\"jsmith@email.com\",\"phone\":\"933123\",\"fldCreated\":\"2018-02-05 12:31:08\",\"fldUpdated\":\"2019-02-04 21:19:31\",\"createdBy\":298,\"updatedBy\":298,\"avgInvoice\":\"\",\"avgPaydays\":\"\",\"percentRev\":\"\",\"companyRegNum\":\"53313334C\",\"fldLEI\":\"No LEI found in SG\",\"fldLEIUpdated\":\"2018-02-05 12:31:00\",\"fldOpenCorpUpdated\":\"2016-12-02 19:44:41\",\"registeredAddress1\":\"50 SERANGOON NORTH AVENUE 4\",\"registeredAddress2\":\"#07-05, FIRST CENTRE,\",\"registeredCounty\":\"SINGAPORE\",\"registeredPostcode\":\"555856\",\"tradingAddressFull\":\"\",\"tradingCountry\":\"\",\"tradingAddress1\":\"50 SERANGOON NORTH AVENUE 4,\",\"tradingAddress2\":\"#07-05\",\"tradingCounty\":\"FIRST CE\",\"tradingPostcode\":\"555856\",\"$$hashKey\":\"object:1524\"},\"seller_name\":\"\",\"seller_id\":\"\",\"buyer_name\":\"\",\"buyer_id\":\"\",\"seller_jurisdiction\":{},\"buyer_jurisdiction\":{},\"full_terms_and_conditions\":\"\",\"contract_price\":3896.16,\"discount\":686.7,\"sales_tax\":649.36,\"charges\":500,\"gross_margin\":-37.34,\"subtotal\":3433.5,\"sales_tax_pc\":20,\"discount_pc\":20,\"costs\":{\"outdated\":false,\"freight\":{\"min\":0,\"max\":0},\"tariffs\":0}},\"status\":\"fulfilled\",\"checks\":[{\"comment\":\"Origin address is not exact\",\"fields\":[\"place_of_despatch\"],\"priority\":\"warning\",\"rank\":5,\"$$hashKey\":\"object:3029\"},{\"comment\":\"Delivery point does not match stated destination country\",\"fields\":[\"Delivery place\",\"Destination country\"],\"priority\":\"warning\",\"rank\":1,\"$$hashKey\":\"object:3030\"},{\"comment\":\"Extra checks may be requested by customs if country of origin does not match place of despatch\",\"fields\":[\"Origin country\",\"Place of despatch\"],\"priority\":\"hint\",\"rank\":1,\"$$hashKey\":\"object:3031\"}],\"contract_price\":null,\"subtotal\":169393,\"discount\":null,\"sales_tax\":null,\"gross_margin\":null}"}
var registeredAddress = [
{
organisation: "PARKWAY LOGIC LTD.",
tradingAddress1: "Nottingham Road",
tradingAddress2: "",
tradingCounty: "Belper",
tradingPostcode: "DE56 1JT",
fldCountry: "United Kingdom"
}
];
var tradingAddress = [
{
organisation: "APOTEX INC.",
tradingAddress1: "1010 Rue de la Gaucheti\u00e8re Ouest ",
tradingAddress2: "Montr\u00e9al",
tradingCounty: "Qu\u00e9bec",
tradingPostcode: "H3B 2N2",
fldCountry: "Canada"
}
];
var consignmentAddress = [
{
organisation: "APOTEX INC.",
registeredAddress1: "Suite 607 Elizabeth Towers, 100 Elizabeth Avenue",
registeredAddress2: "St. John's",
registeredCounty: "NL",
registeredPostcode: "A1B 1S1",
fldCountry: "Canada"
}
];
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.9.1/html2pdf.bundle.min.js"></script>
/* possible to replace with something lie paper-css */
.a4 {
background: white;
width: 21cm;
height: 29.7cm;
display: block;
margin: 0 auto;
position: relative;
padding: 10mm 10mm 10mm 10mm; /* these are like our margins when printing */
margin-bottom: 15mm; /* space between pages */
box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5);
/* overflow-y: scroll; */
box-sizing: border-box;
}
.landscape {
width: 29.7cm;
height: 21cm;
}
.lt { border-left: 1px solid #333; }
.rt { border-right: 1px solid #333; }
.tp { border-top: 1px solid #333; }
.bt { border-bottom: 1px solid #333; }
.grid-container {
display: grid;
}
.grid-container > div {
position:relative;
}
/* Next level down */
.grid-container > div > div {
position:relative;
}
/* Next level down */
.grid-container > div > div > div {
position:relative;
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
/* grid-template-rows: 20px 120px 120px 80px 160px 80px 280px 120px 200px; */
grid-template-rows: 20px 3fr 3fr 2fr 4fr 2fr 7fr 3fr 5fr;
/*padding:2px;*/
grid-gap: 0px 0px;
grid-template-areas: "Title Title" "Seller Admin" "Consignee Buyer" "AdditionalInfo OriginDestinationBank" "Transport Payment" "Shipping Shipping" "Items Items" "Subtotals Subtotals" "Clauses SummarySign";
}
.Title {
grid-area: Title;
font-family: sans-serif;
font-weight:700;
color: #333;
text-align:center;
border:none !important;
}
.Seller { grid-area: Seller; }
.Admin {
display: grid;
grid-area: Admin;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0px 0px;
grid-template-areas: "InvoiceNo PageNo" "InvoiceDate SellerRef" "BuyerRef PurchaseOrderDate";
}
.OriginDestinationBank {
display: grid;
grid-area: OriginDestinationBank;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 0px 0px;
grid-template-areas: "BuyerBank BuyerBank" "OriginCountry DestCountry";
}
.PageNo { grid-area: PageNo;
font-family: sans-serif;
font-weight:700;
color: #333;
font-size: 0.8em;
text-align:center;
padding: 1em;
}
.InvoiceDate { grid-area: InvoiceDate; }
.PurchaseOrderDate { grid-area: PurchaseOrderDate; }
.SellerRef { grid-area: SellerRef; }
.BuyerRef { grid-area: BuyerRef; }
.InvoiceNo { grid-area: InvoiceNo; }
.Consignee { grid-area: Consignee; }
.Buyer { grid-area: Buyer; }
.OriginCountry { grid-area: OriginCountry; }
.DestCountry { grid-area: DestCountry; }
.BuyerBank { grid-area: BuyerBank; }
.Transport {
display: grid;
grid-area: Transport;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 0px 0px;
/* grid-template-areas: "TransportMode DespatchDate" "TransportMean DepatchPlace" "VesselNo LoadingPort" "DischargePort DeliveryPlace"; */
grid-template-areas: "TransportMode ExtraInfo" "DepatchPlace DeliveryPlace";
}
.TransportMode { grid-area: TransportMode; }
.DespatchDate { grid-area: DespatchDate; }
.DepatchPlace { grid-area: DepatchPlace; }
.TransportMean { grid-area: TransportMean; }
.VesselNo { grid-area: VesselNo; }
.LoadingPort { grid-area: LoadingPort; }
.DischargePort { grid-area: DischargePort; }
.DeliveryPlace { grid-area: DeliveryPlace; }
.Payment {
display: grid;
grid-area: Payment;
grid-template-columns: 2fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 0px 0px;
grid-template-areas: "PaymentTerms PaymentCurrency" "SellerBank SellerBank";
}
.PaymentTerms { grid-area: PaymentTerms; }
.PaymentCurrency { grid-area: PaymentCurrency; }
.SellerBank { grid-area: SellerBank; }
.SellerBankDetail { grid-area: SellerBankDetail; }
.Shipping {
display: grid;
grid-area: Shipping;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
grid-gap: 0px 0px;
grid-template-areas: "ShippingMarks PackagesDescription Dimensions";
}
.ShippingMarks { grid-area: ShippingMarks; }
.PackagesDescription { grid-area: PackagesDescription; }
.Dimensions {
display: grid;
grid-area: Dimensions;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 0px 0px;
grid-template-areas: "GrossWt NetWt" "GrossVol .";
}
.GrossWt { grid-area: GrossWt; }
.NetWt { grid-area: NetWt; }
.GrossVol { grid-area: GrossVol; }
.Items {
display: grid;
grid-area: Items;
/* grid-template-columns: 0.5fr 4.3fr 1.2fr 0.8fr 0.9fr 1.3fr;
grid-template-rows: 1fr;
grid-gap: 0px 0px;
grid-template-areas: "ItemNo Description HScode Quantity UnitPrice Amount";
z-index:1000; */
overflow:hidden;
}
.Items table {
/* height:100% !important; */
z-index:10000;
}
.Items table td {
padding-left:3px;
padding-bottom:5px !important;
margin: 0px !important;
height:auto !important;
font-family:'Courier New', Courier, monospace;
font-size:0.75em;
line-height:90%;
vertical-align:top;
}
.ItemsHeadings td {
height:25px !important;
font-size: 0.5em !important;
font-family: sans-serif !important;
font-weight:700 !important;
color: #333 !important;
padding: 3px 3px !important;
z-index:2000 !important;
}
.ItemRow {
/* min-height:14px; */
}
.ItemNo { grid-area: ItemNo; }
.Description { grid-area: Description; }
.HScode { grid-area: HScode; }
.Quantity { grid-area: Quantity; }
.UnitPrice { grid-area: UnitPrice; }
.Amount { grid-area: Amount; }
.ItemNoOverlay { grid-area: ItemNoOverlay; }
.DescriptionOverlay { grid-area: DescriptionOverlay; }
.HScodeOverlay { grid-area: HScodeOverlay; }
.QuantityOverlay { grid-area: QuantityOverlay; }
.UnitPriceOverlay { grid-area: UnitPriceOverlay; }
.AmountOverlay { grid-area: AmountOverlay; }
.Subtotals {
display:grid;
grid-area: Subtotals;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0px 0px;
grid-template-areas: ". . Subtotal" ". . Charges" ". . Deductions";
}
.Subtotal { grid-area: Subtotal; }
.Charges { grid-area: Charges; }
.Deductions { grid-area: Deductions; }
.SummarySign {
display: grid;
grid-area: SummarySign;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr 1fr ;
grid-gap: 0px 0px;
grid-template-areas: "Total" "TotalWords" "SignatureName" "PlaceDate" "Signature";
}
.Clauses { grid-area: Clauses; }
.Total { grid-area: Total; }
.TotalWords { grid-area: TotalWords; }
.SignatureName { grid-area: SignatureName; }
.PlaceDate { grid-area: PlaceDate; }
.Signature { grid-area: Signature; }
.grid-container div {
position: relative;
/* overflow: hidden; */
}
.grid-container input,
.grid-container textarea,
.grid-container select {
width: 100%;
height: 100%;
/* border: 2px solid lightgray; */
background: none;
position: absolute;
z-index: 1;
padding-top: 15px !important;
padding-left: 7px;
padding-right: 7px;
/* 7px 90px 7px;*/
font-family:'Courier New', Courier, monospace;
font-size:0.75em;
line-height:90%;
outline: 0;
overflow:hidden;
}
.grid-container input:valid,
.grid-container textarea:valid {
/*background: white; */
}
.grid-container input:invalid,
.grid-container textarea:invalid {
background: rgb(255, 202, 202);
}
.grid-container input:focus,
.grid-container textarea:focus,
.grid-container select:focus {
/* border-color: cornflowerblue; */
background: rgba(195, 216, 255, 0.486);
/* opacity:100%; */
z-index:100;
}
.grid-container input:focus + label,
.grid-container textarea:focus + label,
.grid-container select:focus + label {
text-transform: uppercase;
}
.grid-container label {
width:100%;
position: absolute;
font-size: 0.5em;
font-family: sans-serif;
font-weight:700;
color: #333;
padding: 0px 3px;
z-index:2000;
}
.grid-container textarea {
border:none !important;
display: block;
resize: none;
}
.grid-container input {
border:none !important;
padding-top:0px;
}
.number-right {
text-align:right;
padding-right:20px;
}
.uib-datepicker-popup.dropdown-menu {
display: block;
float: none;
z-index: 3000 !important;
margin: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment