Compare commits

...

2 Commits

Author SHA1 Message Date
Sergiotarxz 039fa4c785 Adding simple example 2023-09-16 20:53:17 +02:00
Sergiotarxz 7771514bdf Improvements. 2023-09-16 20:53:05 +02:00
6 changed files with 244 additions and 27 deletions

106
burguillos.svg Normal file
View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="120"
height="120"
viewBox="0 0 120 120"
version="1.1"
id="svg5"
sodipodi:docname="burguillos-new-logo.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
inkscape:lockguides="true"
showguides="true"
inkscape:zoom="2.5077712"
inkscape:cx="178.04655"
inkscape:cy="123.21698"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<sodipodi:guide
position="100.2046,119.69309"
orientation="0,-1"
id="guide340"
inkscape:locked="true" />
</sodipodi:namedview>
<defs
id="defs2">
<rect
x="41.461152"
y="93.53679"
width="37.739418"
height="19.063561"
id="rect5477" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#f2eb8c;fill-opacity:1;stroke:#8a2be2;stroke-width:3.484;stroke-dasharray:none;stroke-opacity:1"
d="M 18.028375,5.4640185 C 42.094397,30.546849 65.895567,57.555797 100.66537,4.7964555 145.1512,107.0612 80.481309,117.61217 55.748703,118.50187 1.2161504,117.12284 -2.3973578,49.141609 18.028375,5.4640185 Z"
id="path4249"
sodipodi:nodetypes="cccc" />
<path
style="fill:#8a2be2;fill-opacity:1;stroke:#000000;stroke-width:1.384;stroke-dasharray:none;stroke-opacity:0"
d="m 5.4562907,48.131587 16.9515953,2.646472 80.760414,-2.732742 12.66696,-2.341596 c -2.52037,4.648697 -14.13367,1.691364 -13.49252,8.46198 -5.289214,30.302815 -33.601819,26.392297 -40.414884,8.262841 -4.932324,20.706136 -36.860998,22.078604 -40.624478,-6.767299 -6.19213,-6.378384 -9.17335,-1.03443 -15.8470873,-7.529656 z"
id="path4953"
sodipodi:nodetypes="cccccccc" />
<ellipse
style="fill:#8a2be2;fill-opacity:1;stroke:#000000;stroke-width:1.384;stroke-dasharray:none;stroke-opacity:0"
id="path5421"
cx="62.994671"
cy="84.6521"
rx="5.6541939"
ry="4.5791979" />
<g
aria-label="I"
id="text5475"
style="white-space:pre;shape-inside:url(#rect5477);fill:#8a2be2;fill-opacity:1;stroke:#000000;stroke-width:1.384;stroke-opacity:0"
transform="matrix(3.5861402,4.1249427,-5.3819574,-0.03340189,444.68697,-83.677722)">
<path
d="m 41.396887,94.882854 c 1.567507,0.797149 3.149084,1.398094 4.856457,0.244691 l 0.207593,1.509564 -2,0 v 7.000001 l 2,0 0.428485,1.81474 c -1.67887,-1.50698 -3.974878,-1.43873 -5.631335,-0.17796 l 0.20285,-1.63678 h 2 v -7.000001 l -2,0 z"
style="font-size:12px;font-family:Bangwool;-inkscape-font-specification:'Bangwool, Normal';fill:#8a2be2;fill-opacity:1"
id="path5531"
sodipodi:nodetypes="ccccccccccccc" />
</g>
<path
style="fill:#ffffff;fill-opacity:1;stroke:#8a2be2;stroke-width:0"
d="m 83.352687,48.858635 4.493011,-0.207345 3.889977,24.19843 c -1.014452,1.129583 -0.364441,1.088447 -3.85005,2.494465 1.322091,-16.17219 -1.906635,-20.548093 -4.532938,-26.48555 z"
id="path240"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#8a2be2;stroke-width:0"
d="m 43.326423,50.433596 4.493011,-0.207345 3.889977,24.19843 c -1.014452,1.129583 -0.364441,1.088447 -3.85005,2.494465 1.322091,-16.17219 -1.906635,-20.548093 -4.532938,-26.48555 z"
id="path240-5"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#8a2be2;stroke-width:0"
d="m 92.880587,48.523807 2.506267,-0.152337 2.543723,18.181741 c -0.565875,0.82991 -0.218477,1.571117 -2.162801,2.604125 0.737482,-11.881782 -1.422198,-16.271252 -2.887189,-20.633529 z"
id="path240-6"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#8a2be2;stroke-width:0"
d="m 54.088088,49.92862 2.506267,-0.152337 2.543723,18.181741 c -0.565875,0.82991 -0.218477,1.571117 -2.162801,2.604125 C 57.712759,58.680367 55.553079,54.290897 54.088088,49.92862 Z"
id="path240-6-7"
sodipodi:nodetypes="ccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -2,5 +2,6 @@
"fullname": "Pepito el de los Palotes",
"dni": "12345678A",
"address": "Calle Salvador Allende S/N",
"postal_code": "13243"
"postal_code": "13243",
"img": "burguillos.svg"
}

View File

@ -4,13 +4,13 @@
echo '8'
echo 'y'
echo '2'
echo 'Example concept'
echo '32123123F'
echo 'Peppa Pig'
echo '32454'
echo 'Calle República 14'
echo 'Concepto de prueba'
echo '1'
echo '20.03'
echo 'y'
echo 'Example concept 2'
echo '2'
echo '20.03'
echo '20.00'
echo 'n'
) | perl -Ilib scripts/facturer.pl

12
example_bill_simple.sh Normal file
View File

@ -0,0 +1,12 @@
#!/bin/bash
(
echo '8'
echo 'y'
echo '1'
echo 'Concepto de prueba'
echo '1'
echo '20.00'
echo 'n'
) | perl -Ilib scripts/facturer.pl

View File

@ -32,6 +32,10 @@ sub postal_code ($self) {
return $self->config->{postal_code};
}
sub image ($self) {
return $ROOT_PATH->child($self->config->{img});
}
sub _build_config {
my $config_path = $ROOT_PATH->child('config.json');
return decode_json( $config_path->slurp_utf8 );

View File

@ -24,6 +24,7 @@ my $IVA_INCLUDED = 1;
my $IVA_NOT_INCLUDED = 2;
binmode STDOUT, ':utf8';
binmode STDIN, ':utf8';
sub run ($self) {
my $app = Owlcode::Tech::Facturer->new;
@ -32,8 +33,11 @@ sub run ($self) {
my $self_dni = $app->dni;
my $self_address = $app->address;
my $self_postal_code = $app->postal_code;
my $logo = $app->image;
my $client_dni;
my $client_name;
my $client_postal_code;
my $client_address;
say "Tu nombre completo es $self_name.";
say "Tu dni es $self_dni.";
@ -47,31 +51,37 @@ sub run ($self) {
my $kind_of_bill = $self->ask_kind_of_bill;
say $kind_of_bill;
if ( $kind_of_bill eq $COMPLETA ) {
$client_dni = $self->ask_for_client_dni;
$client_name = $self->ask_for_client_name;
$client_dni = $self->ask_for_client_dni;
$client_name = $self->ask_for_client_name;
$client_postal_code = $self->ask_for_client_postal_code;
$client_address = $self->ask_for_client_address;
}
my $concepts = $self->ask_for_concepts;
print 'Los conceptos son: ' . Data::Dumper::Dumper $concepts;
my $final_data = $self->final_data($concepts);
my $mt = Mojo::Template->new( auto_escape => 1 );
require MIME::Base64;
path("FACTURA @{[sprintf '%06d', $number]}.html")->spew_utf8(
$mt->vars(1)->render(
$self->template_bill,
{
self_name => $self_name,
self_dni => $self_dni,
self_address => $self_address,
self_postal_code => $self_postal_code,
client_dni => $client_dni,
client_name => $client_name,
number => $number,
date => $self->print_date($date),
kind_of_bill => $kind_of_bill,
SIMPLIFICADA => $SIMPLIFICADA,
COMPLETA => $COMPLETA,
concepts => $concepts,
final_data => $final_data,
self_name => $self_name,
self_dni => $self_dni,
self_address => $self_address,
self_postal_code => $self_postal_code,
client_dni => $client_dni,
client_name => $client_name,
client_address => $client_address,
client_postal_code => $client_postal_code,
number => $number,
date => $self->print_date($date),
kind_of_bill => $kind_of_bill,
SIMPLIFICADA => $SIMPLIFICADA,
COMPLETA => $COMPLETA,
concepts => $concepts,
final_data => $final_data,
logo => MIME::Base64::encode_base64($logo->slurp_raw),
}
)
);
@ -83,15 +93,59 @@ sub template_bill ($self) {
<head>
</head>
<body>
<h1>Factura número <%= sprintf '%06d', $number %></h1>
<div class="page-contents">
<img class="logo" src="data:image/svg+xml;base64,<%=$logo%>"/>
<h1>Factura <%=$kind_of_bill eq $SIMPLIFICADA ? 'Simplificada' : 'Completa'%></h1>
<h2>Datos emisor.</h2>
<h2>Datos de factura</h2>
<p>Emitida por <%= $self_name %> con DNI/CIF <%= $self_dni %> en fecha <%= $date %>.</p>
<table>
<tr>
<th>Fecha</th>
<td><%=$date%></td>
</tr>
<tr>
<th>Número</th>
<td><%=$number%></td>
</tr>
</table>
<h2>Datos de emisión recepción.</h2>
<table>
<tr>
<th></th>
<th>Nombre Completo</th>
<th>DNI/CIF/NIE</th>
<th>Código postal</th>
<th>Dirección</th>
</tr>
<tr>
<td>Emisor</td>
<td><%= $self_name %></td>
<td><%= $self_dni %></td>
<td><%= $self_postal_code %></td>
<td><%= $self_address %></td>
</tr>
% if ($kind_of_bill eq $COMPLETA) {
<h2>Datos receptor.</h2>
<p>Destinatario <%= $client_name %> con DNI/CIF <%= $client_dni %>.</p>
<tr>
<td>Receptor</td>
<td><%= $client_name %></td>
<td><%= $client_dni %></td>
<td><%= $client_postal_code %></td>
<td><%= $client_address %></td>
</tr>
% } else {
<tr>
<td>Receptor</td>
<td>Clientes varios</td>
<td>---</td>
<td>---</td>
<td>---</td>
</tr>
% }
</table>
<h2>Desglose factura.</h2>
<table>
@ -124,6 +178,24 @@ sub template_bill ($self) {
<td><%=$final_data->{total}%></td>
</tr>
</table>
</div>
<style>
img.logo {
width: 40px;
aspect-ratio: 1 / 1;
}
div.page-contents {
display: flex;
flex-direction: column;
align-items: start;
}
h1 {
align-self: center;
}
td,th {
border: solid 1px black;
}
</style>
</body>
</html>
EOF
@ -150,6 +222,28 @@ sub final_data ( $self, $concepts ) {
};
}
sub ask_for_client_postal_code ($self) {
my $input;
while ( !defined $input || $input =~ /^\s*$/ ) {
print "Introduce el código postal del cliente o su empresa
> ";
$input = <STDIN>;
chomp $input;
}
return $input;
}
sub ask_for_client_address ($self) {
my $input;
while ( !defined $input || $input =~ /^\s*$/ ) {
print "Introduce la dirección (calle y número) del cliente o su empresa
> ";
$input = <STDIN>;
chomp $input;
}
return $input;
}
sub ask_for_client_name ($self) {
my $input;
while ( !defined $input || $input =~ /^\s*$/ ) {