Compare commits

...

4 Commits

Author SHA1 Message Date
f709c11d00 import apilo 2025-09-25 20:59:26 +00:00
Michał Zieliński
aa4a2a6ebb import apilo invoices 2025-09-25 22:33:49 +02:00
Michał Zieliński
508cde0a68 import apilo invoices 2025-09-25 21:50:59 +02:00
7943842f90 amazon august 2025-09-24 06:38:38 +00:00
15 changed files with 1822 additions and 11 deletions

View File

@@ -0,0 +1,452 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Author: Eugene Kin Chee Yip
# Date: 7 Nov 2008
import cherrypy
import socket
import math
import openFlashChart
from openFlashChart_varieties import (Line,
Line_Dot,
Line_Hollow,
Bar,
Bar_Filled,
Bar_Glass,
Bar_3d,
Bar_Sketch,
HBar,
Bar_Stack,
Area_Line,
Area_Hollow,
Pie,
Scatter,
Scatter_Line)
from openFlashChart_varieties import (dot_value,
hbar_value,
bar_value,
bar_3d_value,
bar_glass_value,
bar_sketch_value,
bar_stack_value,
pie_value,
scatter_value,
x_axis_labels,
x_axis_label)
class OFC:
@cherrypy.expose
def index(self):
graphs = []
# Line Charts
graphs.append(openFlashChart.flashHTML('100%', '400', '/line', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/line_dot', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/line_hollow', '/flashes/'))
# Bar Charts
graphs.append(openFlashChart.flashHTML('100%', '400', '/bar', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/bar_filled', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/bar_glass', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/bar_3d', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/bar_sketch', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/hbar', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/bar_stack', '/flashes/'))
# Area Charts
graphs.append(openFlashChart.flashHTML('100%', '400', '/area_line', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/area_hollow', '/flashes/'))
# Pie Chart
graphs.append(openFlashChart.flashHTML('100%', '400', '/pie', '/flashes/'))
# Scatter Charts
graphs.append(openFlashChart.flashHTML('100%', '400', '/scatter', '/flashes/'))
graphs.append(openFlashChart.flashHTML('100%', '400', '/scatter_line', '/flashes/'))
# Radar Charts
graphs.append(openFlashChart.flashHTML('100%', '400', '/radar', '/flashes/'))
# Testing Chart
graphs.append(openFlashChart.flashHTML('100%', '400', '/test', '/flashes/'))
graphs.append(self.source("html_snippet.html"))
return self.source("OFC.htm") %({"chart": "<br/><br/><br/><br/>".join(graphs)})
# Line Charts
@cherrypy.expose
def line(self):
plot1 = Line(text = "line1", fontsize = 20, values = range(0,10))
plot2 = Line(text = "line2", fontsize = 06, values = range(10,0, -1))
plot3 = Line(text = "line3", fontsize = 12, values = range(-5,5))
plot1.set_line_style(4, 3)
plot2.set_line_style(5, 5)
plot3.set_line_style(4, 8)
plot1.set_colour('#D4C345')
plot2.set_colour('#C95653')
plot3.set_colour('#8084FF')
chart = openFlashChart.template("Line chart")
chart.set_y_axis(min = -6, max = 10)
chart.add_element(plot1)
chart.add_element(plot2)
chart.add_element(plot3)
return chart.encode()
@cherrypy.expose
def line_dot(self):
plot1 = Line_Dot(values = [math.sin(float(x)/10) * 1.9 + 4 for x in range(0, 62, 2)])
plot2 = Line_Dot(values = [math.sin(float(x)/10) * 1.9 + 7 for x in range(0, 62, 2)])
plot3 = Line_Dot(values = [math.sin(float(x)/10) * 1.9 + 10 for x in range(0, 62, 2)])
plot1.set_halo_size(0)
plot2.set_halo_size(1)
plot3.set_halo_size(3)
plot1.set_width(1)
plot2.set_width(2)
plot3.set_width(6)
plot1.set_dot_size(4)
plot2.set_dot_size(4)
plot3.set_dot_size(6)
chart = openFlashChart.template("Line_Dot chart")
chart.set_y_axis(min = 0, max = 15, steps = 5)
chart.add_element(plot1)
chart.add_element(plot2)
chart.add_element(plot3)
return chart.encode()
@cherrypy.expose
def line_hollow(self):
plot1 = Line_Hollow(values = [math.sin(float(x)/10) * 1.9 + 4 for x in range(0, 62, 2)])
plot2 = Line_Hollow(values = [math.sin(float(x)/10) * 1.9 + 7 for x in range(0, 62, 2)])
plot3 = Line_Hollow(values = [math.sin(float(x)/10) * 1.9 + 10 for x in range(0, 62, 2)])
plot1.set_halo_size(3)
plot2.set_halo_size(1)
plot3.set_halo_size(0)
plot1.set_width(1)
plot2.set_width(2)
plot3.set_width(3)
plot1.set_dot_size(4)
plot2.set_dot_size(4)
plot3.set_dot_size(6)
chart = openFlashChart.template("Line_Hollow chart")
chart.set_y_axis(min = 0, max = 15, steps = 5)
chart.add_element(plot1)
chart.add_element(plot2)
chart.add_element(plot3)
return chart.encode()
# Bar Charts
@cherrypy.expose
def bar(self):
plot = Bar(text = "bar1", values = range(9, 0, -1))
chart = openFlashChart.template("Bar chart")
chart.add_element(plot)
return chart.encode()
@cherrypy.expose
def bar_filled(self):
plot = Bar_Filled(values = range(9, 0, -1) + [bar_value((5, 3), '#AAAAAA', 'Special:<br>Top = #top#<br>Bottom = #bottom#')], colour = '#E2D66A', outline = '#577261')
chart = openFlashChart.template("Bar_Filled chart",)
chart.add_element(plot)
chart.set_bg_colour('#FFFFFF')
return chart.encode()
@cherrypy.expose
def bar_glass(self):
plot = Bar_Glass(values = range(-5, 5, 2) + [bar_glass_value(5, '#333333', 'Special:<br>Top = #top#<br>Bottom = #bottom#')])
chart = openFlashChart.template("Bar_Glass chart")
chart.set_y_axis(min = -6, max = 6)
chart.add_element(plot)
return chart.encode()
@cherrypy.expose
def bar_3d(self):
plot = Bar_3d(values = range(-8, 8, 2) + [bar_3d_value(5, '#333333', 'Special:<br>Top = #top#<br>Bottom = #bottom#')])
plot.set_colour('#D54C78')
chart = openFlashChart.template("Bar_3d chart")
chart.set_y_axis(min = -8, max = 8)
chart.set_x_axis(colour = '#909090', three_d = 5, labels = list('qp#m^fur'))
chart.add_element(plot)
return chart.encode()
@cherrypy.expose
def bar_sketch(self):
plot1 = Bar_Sketch(values = range(10, 0, -1) + [bar_sketch_value(5, '#333333', 'Special:<br>Top = #top#')], colour = '#81AC00', outline = '#567300')
plot2 = Bar_Sketch(values = [bar_sketch_value(5, '#333333', 'Special:<br>Top = #top#')] + range(10, 0, -1), colour = '#81ACFF', outline = '#5673FF')
chart = openFlashChart.template("Bar_Sketch chart", style = '{color: #567300; font-size: 14px}')
chart.add_element(plot1)
chart.add_element(plot2)
return chart.encode()
@cherrypy.expose
def hbar(self):
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
plot = HBar(colour = '#86BBEF')
plot.set_tooltip('Months: #val#')
plot.append_values(hbar_value((0, 4), colour = '#909090'))
plot.append_values(hbar_value((4, 8), colour = '#909009'))
plot.append_values(hbar_value((8, 11), tooltip = '#left# to #right#<br>%s to %s (#val# months)' %(months[8], months[11])))
chart = openFlashChart.template("HBar chart")
chart.set_x_axis(offset = False, labels = x_axis_labels(labels = months))
chart.set_y_axis(offset = True, labels = ['one', 'two', 'three'])
chart.add_element(plot)
return chart.encode()
@cherrypy.expose
def bar_stack(self):
plot = Bar_Stack(colours = ['#C4D318', '#50284A', '#7D7B6A'])
plot.set_tooltip('X label [#x_label#], Value [#val#]<br>Total [#total#]')
plot.append_keys('#C4D318', 'job1', 13)
plot.append_keys('#50284A', 'job2', 13)
plot.append_keys('#7D7B6A', 'job3', 13)
plot.append_keys('#ff0000', 'job4', 13)
plot.append_keys('#ff00ff', 'job5', 13)
plot.append_stack([2.5, 5, 2.5])
plot.append_stack([2.5, 5, 1.25, 1.25])
plot.append_stack([5, bar_stack_value(5, '#ff0000')])
plot.append_stack([2, 2, 2, 2, bar_stack_value(2, '#ff00ff')])
chart = openFlashChart.template("Bar_Stack chart", style = '{font-size: 20px; color: #F24062; text-align: center;}')
chart.set_tooltip(behaviour = 'hover')
chart.set_x_axis(labels = x_axis_labels(labels = ['Winter', 'Spring', 'Summer', 'Autumn']))
chart.set_y_axis(min = 0, max = 14, steps = 2)
chart.add_element(plot)
return chart.encode()
# Area charts
@cherrypy.expose
def area_line(self):
plot = Area_Line(colour = '#C4B86A', fill = '#C4B86A', fill_alpha = 0.7, values = [math.sin(float(x)/10) * 1.9 for x in range(0, 62, 2)])
plot.set_halo_size(1)
plot.set_width(2)
plot.set_dot_size(4)
chart = openFlashChart.template("Area_Line chart")
chart.set_y_axis(min = -2, max = 2, steps = 2, offset = True)
chart.set_x_axis(labels = x_axis_labels(labels = ['%d' %i for i in range(0, 62, 2)], steps = 4, rotate = 'vertical'), steps = 2)
chart.add_element(plot)
return chart.encode()
@cherrypy.expose
def area_hollow(self):
plot = Area_Hollow(colour = '#838A96', fill = '#E01B49', fill_alpha = 0.4, values = [math.sin(float(x)/10) * 1.9 for x in range(0, 62, 2)])
plot.set_halo_size(1)
plot.set_width(2)
plot.set_dot_size(4)
chart = openFlashChart.template("Area_Hollow chart")
chart.set_y_axis(min = -2, max = 2, steps = 2, offset = False)
chart.set_x_axis(labels = x_axis_labels(rotate = 'diagonal'), steps = 2)
chart.add_element(plot)
return chart.encode()
# Pie chart
@cherrypy.expose
def pie(self):
plot = Pie(start_angle = 35, animate = True, values = [2, 3, pie_value(6.5, ('hello (6.5)', '#FF33C9', 24))], colours = ['#D01F3C', '#356AA0', '#C79810'], label_colour = '#432BAF')
plot.set_tooltip('#val# of #total#<br>#percent# of 100%')
plot.set_gradient_fill(True)
plot.set_on_click('plot1')
plot.set_no_labels(False)
chart = openFlashChart.template("Pie chart")
chart.add_element(plot)
return chart.encode()
# Scatter charts
@cherrypy.expose
def scatter(self):
radians = [math.radians(degree) for degree in xrange(0, 360, 5)]
values = [scatter_value(('%.2f' %math.sin(radian), '%.2f' %math.cos(radian))) for radian in radians]
plot1 = Scatter(colour = '#FFD600', values = [scatter_value((0, 0))])
plot2 = Scatter(colour = '#D600FF', values = values)
plot1.set_dot_size(10)
plot2.set_dot_size(3)
chart = openFlashChart.template("Scatter chart")
chart.set_x_axis(min = -2, max = 3)
chart.set_y_axis(min = -2, max = 2)
chart.add_element(plot1)
chart.add_element(plot2)
return chart.encode()
@cherrypy.expose
def scatter_line(self):
from random import randint
x_values = [0]
while x_values[-1] < 25:
x_values.append(x_values[-1] + float(randint(5, 15))/10)
values = [scatter_value((x, float(randint(-15, 15))/10)) for x in x_values]
plot = Scatter_Line(colour = '#FFD600', values = values)
plot.set_dot_size(3)
chart = openFlashChart.template("Scatter_Line chart")
chart.set_x_axis(min = 0, max = 25)
chart.set_y_axis(min = -10, max = 10)
chart.add_element(plot)
return chart.encode()
# Radar Charts
@cherrypy.expose
def radar(self):
plot = Area_Hollow(colour = '#45909F', fill = '#45909F', fill_alpha = 0.4, values = [3, 4, 5, 4, 3, 3, 2.5])
plot.set_width(1)
plot.set_dot_size(4)
plot.set_halo_size(1)
plot.set_loop()
chart = openFlashChart.template("Radar chart")
chart.set_bg_colour('#DFFFEC')
chart.set_radar_axis(max = 5, colour = '#EFD1EF', grid_colour = '#EFD1EF', labels = list('012345'), spoke_labels = list('1234567'))
chart.set_tooltip(behaviour = 'proximity')
chart.add_element(plot)
return chart.encode()
# Testing Graph
@cherrypy.expose
def test(self):
plot1 = Line(text = "line1", fontsize = 20, values = [None, 5, 1, 2, 4, None, None, 2, 7, 5])
plot2 = Line(text = "line2", fontsize = 12, values = range(-4, 7, 1))
plot3 = Bar_Glass(text = "bar1", values = [4, None, -4, 3, bar_glass_value((5, -2), '#333333', 'Special:<br>Top = #top#<br>Bottom = #bottom#'), 7, None, None, -5, 5])
plot1.set_tooltip('Title1:<br>Amount = #val#')
plot2.set_tooltip('Title2:<br>Value = #val#')
plot3.set_tooltip('Title3:<br>Height = #val#')
plot1.set_on_click('plot1')
plot2.set_on_click('plot2')
plot1.set_line_style(4, 3)
plot2.set_line_style(4, 8)
plot1.set_colour('#D4C345')
plot2.set_colour('#8084FF')
plot3.set_colour('#FF84FF')
chart = openFlashChart.template("Testing chart", style = '{font-size: 40px; font-family: Times New Roman; color: #A2ACBA; text-align: right;}')
chart.set_x_axis(stroke = 10, colour = '#165132', tick_height = 30, grid_colour = '#AAEE00', offset = True, steps = 2, labels = x_axis_labels(labels = list('sfwertr56w') + [x_axis_label('custom!!', '#2683CF', 24, 'diagonal')], steps = 2))
chart.set_y_axis(stroke = 5, colour = '#1E33FF', tick_length = 15, grid_colour = '#090305', offset = True, steps = 4, min = -6)
chart.set_y_axis_right(stroke = 5, colour = '#44FF22', tick_length = 20, grid_colour = '#55ff55', offset = True, steps = 1)
chart.set_x_legend("x-axis legend", style = '{font-size: 20px; color: #778877}')
chart.set_y_legend("y-axis legend", style = '{font-size: 22px; color: #778877}')
chart.set_tooltip(shadow = True, stroke = 4, colour = '#909090', bg_colour = '#FAFAFA', title_style = '{font-size: 14px; color: #CC2A43;}', body_style = '{font-size: 10px; font-weight: bold; color: #000000;}')
chart.add_element(plot1)
chart.add_element(plot2)
chart.add_element(plot3)
return chart.encode()
@cherrypy.expose
def ajax(self, count):
if int(count) % 3 is 0:
plot = Line_Dot(text = "line1", fontsize = 20, values = [None, 5, dot_value(1, '#D02020', '#val#<br>Text'), 2, 4, None, None, 2, 7, 5])
elif int(count) % 3 is 1:
plot = Line(text = "line2", fontsize = 12, values = range(-4, 7, 1))
else:
plot = Bar_Glass(text = "bar1", values = [4, None, -4, 3, bar_glass_value((5, -2), '#333333', 'Special:<br>Top = #top#<br>Bottom = #bottom#'), 7, None, None, -5, 5])
plot.set_tooltip('Title1:<br>Amount = #val#')
plot.set_on_click('plot1')
plot.set_line_style(4, 3)
plot.set_colour('#D4C345')
chart = openFlashChart.template("Testing chart: %s" %count, style = '{font-size: 40px; font-family: Times New Roman; color: #A2ACBA; text-align: right;}')
chart.set_x_axis(stroke = 10, colour = '#165132', tick_height = 30, grid_colour = '#AAEE00', offset = True, steps = 2, labels = x_axis_labels(labels = list('sfwertr56w') + [x_axis_label('custom!!', '#2683CF', 24, 210)], steps = 2))
chart.set_y_axis(stroke = 5, colour = '#1E33FF', tick_length = 15, grid_colour = '#090305', offset = True, steps = 4, min = -6)
chart.set_y_axis_right(stroke = 5, colour = '#44FF22', tick_length = 20, grid_colour = '#55ff55', offset = True, steps = 1)
chart.set_x_legend("x-axis legend", style = '{font-size: 20px; color: #778877}')
chart.set_y_legend("y-axis legend", style = '{font-size: 22px; color: #778877}')
chart.set_tooltip(shadow = True, stroke = 4, colour = '#909090', bg_colour = '#FAFAFA', title_style = '{font-size: 14px; color: #CC2A43;}', body_style = '{font-size: 10px; font-weight: bold; color: #000000;}')
chart.add_element(plot)
return chart.encode()
def source(self, filename):
"""Opens a file specified by the file/pathname in read-only"""
file = open(filename, 'r')
result = file.read()
file.close()
return result
@cherrypy.expose
def flashes(self, filename):
cherrypy.response.headers['Content-Type'] = "application/x-shockwave-flash"
cherrypy.response.headers['Expires'] = "Tue, 01 Dec 2009 12:00:00 GMT"
cherrypy.response.headers['Cache-Control'] = "Public"
return open(filename)
cherrypy.server.socket_host = socket.gethostbyname(socket.gethostname())
cherrypy.quickstart(OFC(), config = 'serverconfig.conf')

View File

@@ -0,0 +1,88 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Author: Emanuel Fonseca
# Email: emdfonseca<at>gmail<dot>com
# Date: 25 August 2008
#
# Author: Eugene Kin Chee Yip
# Date: 7 Nov 2008
import cjson
from openFlashChart_elements import (title,
x_legend,
y_legend,
x_axis,
y_axis,
radar_axis,
tooltip)
def flashHTML(width, height, url, ofc_base_url="/flashes/", ofc_swf="OFC.swf" ):
return (
"""
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0"
width="%(width)s" height="%(height)s" id="chart" align="middle">
<param name="allowScriptAccess" value="sameDomain"/>
<param name="movie" value="%(ofc_base_url)s%(ofc_swf)s"/>
<param name="FlashVars" value="data-file=%(url)s"/>
<param name="quality" value="high"/>
<param name="bgcolor" value="#FFFFFF"/>
<embed src="%(ofc_base_url)s%(ofc_swf)s" FlashVars="data-file=%(url)s" quality="high" bgcolor="#FFFFFF"
width=%(width)s height=%(height)s name="chart" align="middle" allowScriptAccess="sameDomain"
type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"/>
</object>
""") % locals()
class template(dict):
def __init__(self, title_string, style = None):
self['title'] = title(title_string, style)
def set_x_legend(self, legend, style):
self['x_legend'] = x_legend(legend, style)
def set_y_legend(self, legend, style):
self['y_legend'] = y_legend(legend, style)
def set_x_axis(self, stroke = None, tick_height = None, colour = None, grid_colour = None, labels = None, three_d = None, max = None, min = None, steps = None, offset = None):
self['x_axis'] = x_axis(stroke, tick_height, colour, grid_colour, labels, three_d, max, min, steps, offset)
def set_y_axis(self, stroke = None, tick_length = None, colour = None, grid_colour = None, labels = None, max = None, min = None, steps = None, offset = None):
self['y_axis'] = y_axis(stroke, tick_length, colour, grid_colour, labels, max, min, steps, offset)
def set_y_axis_right(self, stroke = None, tick_length = None, colour = None, grid_colour = None, labels = None, max = None, min = None, steps = None, offset = None):
self['y_axis_right'] = y_axis(stroke, tick_length, colour, grid_colour, labels, max, min, steps, offset)
def set_radar_axis(self, stroke = None, tick_height = None, colour = None, grid_colour = None, labels = None, max = None, min = None, steps = None, spoke_labels = None):
self['radar_axis'] = radar_axis(stroke, tick_height, colour, grid_colour, labels, max, min, steps, spoke_labels)
def set_bg_colour(self, colour):
self['bg_colour'] = colour
def set_tooltip(self, shadow = None, stroke = None, colour = None, bg_colour = None, title_style = None, body_style = None, behaviour = None):
self['tooltip'] = tooltip(shadow, stroke, colour, bg_colour, title_style, body_style, behaviour)
def add_element(self, element):
try:
self['elements'].append(element)
except:
self['elements'] = [element]
def encode(self):
return cjson.encode(self)

View File

@@ -0,0 +1,163 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Author: Emanuel Fonseca
# Email: emdfonseca<at>gmail<dot>com
# Date: 25 August 2008
#
# Author: Eugene Kin Chee Yip
# Date: 7 Nov 2008
##########################################
# title class
class title(dict):
def __init__(self, title, style=None):
self['text'] = title
self.set_style(style)
def set_style(self, style):
self['style'] = style if style else '{color: #000000; font-size: 12px;}'
class y_legend(title):
pass
class x_legend(title):
pass
##########################################
# axis classes
class axis(dict):
def __init__(self, stroke = None, colour = None, grid_colour = None, labels = None, max = None, min = None, steps = None, offset = None):
self.set_stroke(stroke)
self.set_colour(colour)
self.set_grid_colour(grid_colour)
self.set_labels(labels)
self.set_steps(steps)
self.set_offset(offset)
self.set_max(max)
self.set_min(min)
def set_stroke(self, stroke):
if stroke:
self['stroke'] = stroke
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_grid_colour(self, grid_colour):
if grid_colour:
self['grid-colour'] = grid_colour
def set_labels(self, labels):
if labels:
self['labels'] = labels
def set_steps(self, steps):
if steps:
self['steps'] = steps
def set_offset(self, offset):
if offset is not None:
self['offset'] = offset
def set_max(self, max):
if max:
self['max'] = max
def set_min(self, min):
if min:
self['min'] = min
class x_axis(axis):
def __init__(self, stroke = None, tick_height = None, colour = None, grid_colour = None, labels = None, three_d = None, max = None, min = None, steps = None, offset = None):
axis.__init__(self, stroke, colour, grid_colour, labels, max, min, steps, offset)
self.set_tick_height(tick_height)
self.set_3d(three_d)
def set_tick_height(self, tick_height):
if tick_height:
self['tick-height'] = tick_height
def set_3d(self, three_d):
if three_d:
self['3d'] = three_d
class y_axis(axis):
def __init__(self, stroke = None, tick_length = None, colour = None, grid_colour = None, labels = None, max = None, min = None, steps = None, offset = None):
axis.__init__(self, stroke, colour, grid_colour, labels, max, min, steps, offset)
self.set_tick_length(tick_length)
self.set_offset(offset)
def set_tick_length(self, tick_length):
if tick_length:
self['tick-length'] = tick_length
class radar_axis(axis):
def __init__(self, stroke = None, tick_height = None, colour = None, grid_colour = None, labels = None, max = None, min = None, steps = None, spoke_labels = None):
axis.__init__(self, stroke, colour, grid_colour, labels, max, min, steps)
self.set_tick_height(tick_height)
self.set_spoke_labels(spoke_labels)
def set_tick_height(self, tick_height):
if tick_height:
self['tick-height'] = tick_height
def set_spoke_labels(self, spoke_labels):
if spoke_labels:
self['spoke-labels'] = {'labels': spoke_labels}
##########################################
# tooltip class
class tooltip(dict):
def __init__(self, shadow = None, stroke = None, colour = None, bg_colour = None, title_style = None, body_style = None, behaviour = None):
self.set_shadow(shadow)
self.set_stroke(stroke)
self.set_colour(colour)
self.set_background(bg_colour)
self.set_title(title_style)
self.set_body(body_style)
self.set_behaviour(behaviour)
def set_shadow(self, shadow):
if shadow is not None:
self['shadow'] = shadow
def set_stroke(self, stroke):
if stroke:
self['stroke'] = stroke
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_background(self, background):
if background:
self['background'] = background
def set_title(self, title):
if title:
self['title'] = title
def set_body(self, body):
if body:
self['body'] = body
def set_behaviour(self, behaviour):
if behaviour == 'proximity':
self['mouse'] = 1
if behaviour == 'hover':
self['mouse'] = 2

View File

@@ -0,0 +1,391 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Author: Emanuel Fonseca
# Email: emdfonseca<at>gmail<dot>com
# Date: 25 August 2008
#
# Author: Eugene Kin Chee Yip
# Date: 7 Nov 2008
class varieties(dict):
def __init__(self, type = None, alpha = None, colour = None, text = None, fontsize = None, values = None):
self.set_type(type)
self.set_alpha(alpha)
self.set_colour(colour)
self.set_text(text)
self.set_fontsize(fontsize)
self.set_values(values)
def set_type(self, type):
if type:
self['type'] = type
def set_alpha(self, alpha):
if alpha:
self['alpha'] = alpha
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_gradient_fill(self, gradient_fill):
self['gradient-fill'] = gradient_fill
def set_halo_size(self, size):
self['halo-size'] = size
def set_width(self, width):
self['width'] = width
def set_dot_size(self, size):
self['dot-size'] = size
def set_text(self, text):
if text:
self['text'] = text
def set_fontsize(self, fontsize):
if fontsize:
self['font-size'] = fontsize
def set_values(self, values):
if values:
self['values'] = values
def append_keys(self, colour = None, text = None, fontsize = None):
try:
self['keys'].append(bar_stack_key(colour, text, fontsize))
except:
self['keys'] = [bar_stack_key(colour, text, fontsize)]
def append_values(self, values):
try:
self['values'].append(values)
except:
self['values'] = [values]
def append_stack(self, values):
self.append_values(values)
def set_line_style(self, on, off):
self['line-style'] = line_style(on, off)
def set_tooltip(self, text):
self['tip'] = text
def set_no_labels(self, no_labels):
self['no-labels'] = no_labels
def set_loop(self):
self['loop'] = True
def set_on_click(self, javascript_call):
self['on-click'] = javascript_call
##########################################
# key class for bar stack
class bar_stack_key(dict):
def __init__(self, colour = None, text = None, fontsize = None):
self.set_colour(colour)
self.set_text(text)
self.set_fontsize(fontsize)
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_text(self, text):
if text:
self['text'] = text
def set_fontsize(self, fontsize):
if fontsize:
self['font-size'] = fontsize
##########################################
# value class for custom data points
class value(dict):
def __init__(self, val = None, colour = None, tooltip = None):
self.set_val(val)
self.set_colour(colour)
self.set_tooltip(tooltip)
def set_val(self, val):
if val:
self['value'] = val
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_tooltip(self, tooltip):
if tooltip:
self['tip'] = tooltip
class dot_value(value):
pass
class bar_value(value):
def __init__(self, (top, bottom), colour = None, tooltip = None):
value.__init__(self, colour = colour, tooltip = tooltip)
self.set_top_value(top)
self.set_bottom_value(bottom)
def set_top_value(self, top):
self['top'] = top
def set_bottom_value(self, bottom):
self['bottom'] = bottom
class bar_3d_value(bar_value):
def __init__(self, top, colour = None, tooltip = None):
value.__init__(self, colour = colour, tooltip = tooltip)
self.set_top_value(top)
def set_top_value(self, top):
self['top'] = top
class bar_glass_value(bar_3d_value):
pass
class bar_sketch_value(bar_3d_value):
pass
class hbar_value(value):
def __init__(self, (left, right), colour = None, tooltip = None):
value.__init__(self, colour = colour, tooltip = tooltip)
self.set_left_value(left)
self.set_right_value(right)
def set_left_value(self, left):
self['left'] = left
def set_right_value(self, right):
self['right'] = right
class bar_stack_value(value):
def __init__(self, val, colour = None, tooltip = None):
value.__init__(self, colour = colour, tooltip = tooltip)
self.set_value(val)
def set_value(self, val):
if val:
self['val'] = val
class pie_value(value):
def __init__(self, val, label = None, colour = None, tooltip = None):
value.__init__(self, val, colour, tooltip)
self.set_label(label)
def set_label(self, (label, colour, fontsize)):
if label:
self['label'] = label
if colour:
self['label-colour'] = colour
if fontsize:
self['font-size'] = fontsize
class scatter_value(value):
def __init__(self, (x, y), colour = None, tooltip = None):
value.__init__(self, colour = colour, tooltip = tooltip)
self.set_x_value(x)
self.set_y_value(y)
def set_x_value(self, x):
self['x'] = x
def set_y_value(self, y):
self['y'] = y
##########################################
# line style class for charts with lines
class line_style(dict):
def __init__(self, on = None, off = None, style = 'dash'):
self.set_style(style)
self.set_on(on)
self.set_off(off)
def set_style(self, style):
self['style'] = style
def set_on(self, on):
if on:
self['on'] = on
def set_off(self, off):
if off:
self['off'] = off
##########################################
# label classes
class x_axis_labels(dict):
def __init__(self, labels = None, steps = None, colour = None, size = None, rotate = None):
self.set_labels(labels)
self.set_steps(steps)
self.set_colour(colour)
self.set_size(size)
self.set_rotate(rotate)
def set_labels(self, labels):
if labels:
self['labels'] = labels
def set_steps(self, steps):
if steps:
self['steps'] = steps
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_size(self, size):
if size:
self['size'] = size
def set_rotate(self, rotate):
if rotate:
self['rotate'] = rotate
class x_axis_label(dict):
def __init__(self, text = None, colour = None, size = None, rotate = None):
self.set_text(text)
self.set_colour(colour)
self.set_size(size)
self.set_rotate(rotate)
def set_text(self, text):
if text:
self['text'] = text
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_size(self, size):
if size:
self['size'] = size
def set_rotate(self, rotate):
if rotate:
self['rotate'] = rotate
##########################################
# Chart classes
# Line Charts
class Line(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None):
varieties.__init__(self, 'line', alpha, colour, text, fontsize, values)
class Line_Dot(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None):
varieties.__init__(self, 'line_dot', alpha, colour, text, fontsize, values)
class Line_Hollow(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None):
varieties.__init__(self, 'line_hollow', alpha, colour, text, fontsize, values)
# Bar Charts
class Bar(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None):
varieties.__init__(self, 'bar', alpha, colour, text, fontsize, values)
class Bar_Filled(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, outline = None):
varieties.__init__(self, 'bar_filled', alpha, colour, text, fontsize, values)
if outline:
self['outline-colour'] = outline
class Bar_Glass(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None):
varieties.__init__(self, 'bar_glass', alpha, colour, text, fontsize, values)
class Bar_3d(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None):
varieties.__init__(self, 'bar_3d', alpha, colour, text, fontsize, values)
class Bar_Sketch(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, outline = None):
varieties.__init__(self, 'bar_sketch', alpha, colour, text, fontsize, values)
if outline:
self['outline-colour'] = outline
class HBar(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None):
varieties.__init__(self, 'hbar', alpha, colour, text, fontsize, values)
class Bar_Stack(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, colours = None):
varieties.__init__(self, 'bar_stack', alpha, colour, text, fontsize, values)
if colours:
self['colours'] = colours
# Area Charts
class Area_Line(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, fill = None, fill_alpha = None):
varieties.__init__(self, 'area_line', alpha, colour, text, fontsize, values)
if fill_alpha:
self['fill-alpha'] = fill_alpha
if fill:
self['fill'] = fill
class Area_Hollow(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, fill = None, fill_alpha = None):
varieties.__init__(self, 'area_hollow', alpha, colour, text, fontsize, values)
if fill_alpha:
self['fill-alpha'] = fill_alpha
if fill:
self['fill'] = fill
# Pie Chart
class Pie(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, start_angle = None, animate = None, colours = None, label_colour = None):
varieties.__init__(self, 'pie', alpha, colour, text, fontsize, values)
if start_angle:
self['start-angle'] = start_angle
if animate:
self['animate'] = animate
if colours:
self['colours'] = colours
if label_colour:
self['label-colour'] = label_colour
# Scatter Charts
class Scatter(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, colours = None):
varieties.__init__(self, 'scatter', alpha, colour, text, fontsize, values)
class Scatter_Line(varieties):
def __init__(self, alpha = None, colour = None, text = None, fontsize = None, values = None, colours = None):
varieties.__init__(self, 'scatter_line', alpha, colour, text, fontsize, values)

View File

@@ -0,0 +1,136 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Author: Emanuel Fonseca
# Email: emdfonseca<at>gmail<dot>com
# Date: 25 August 2008
import cherrypy
from string import Template
import datetime
import ofc2
from ofc2_element import Line, Bar, BarStack
xhtml_template = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<script type="text/javascript" src="/static/swfobject.js"></script>
<script type="text/javascript">
$js
</script>
<head>
<title>$title</title>
</head>
<body>
$body
</body>
</html>
"""
jstpl = Template('swfobject.embedSWF("/static/open-flash-chart.swf","$title", "$width", "$height", "$flash_ver", "expressInstall.swf", {"data-file": "$data_src"});\n')
dvtpl = Template('<h1>$title</h1><div id="$title"></div><br/>\n')
class Chart(object):
type = ''
title = 'chart'
width=400
height=200
flash_ver='9.0.0'
data_src = None
chart = None
def index(self):
return self.chart.encode()
index.exposed = True
def __init__(self, type, name):
self.title = name
self.data_src='/'+name
def get_js(self):
return jstpl.substitute(title=self.title, width=self.width, height=self.height, flash_ver = self.flash_ver, data_src = self.data_src)
def get_div(self):
return dvtpl.substitute(title=self.title)
class BarChart(Chart):
def __init__(self, type, name):
Chart.__init__(self, type, name)
# create the bar element and set its values
element = Bar(values=[9,8,7,6,5,4,3,2,1])
# create the chart and set its title
self.chart = ofc2.open_flash_chart(title=str(datetime.datetime.now()))
self.chart.add_element(element)
class BarStackChart(Chart):
def __init__(self, type, name):
Chart.__init__(self, type, name)
# create the bar element and set its values
element = BarStack(values=[ [ 2.5, 5 ], [ 7.5 ], [ 5, { 'val': 5, 'colour': '#ff0000' } ], [ 2, 2, 2, 2, { "val": 2, 'colour': '#ff00ff' } ] ])
# create the chart and set its title
self.chart = ofc2.open_flash_chart(title=str(datetime.datetime.now()))
self.chart.set_y_axis(min=0, max=14, steps=7)
self.chart.set_x_axis(labels=['a', 'b', 'c', 'd'])
self.chart.add_element(element)
class LineChart(Chart):
def __init__(self, type, name):
Chart.__init__(self, type, name)
# create the bar element and set its values
element = Line(values=[9,8,7,6,5,4,3,2,1])
# create the chart and set its title
self.chart = ofc2.open_flash_chart(title=str(datetime.datetime.now()))
self.chart.add_element(element)
class OFC2Demo(object):
tpl = Template(xhtml_template)
swfobjs = ''
divs = ''
linechart = LineChart('line_chart', 'linechart') # var name must be the same as the second param
barchart = BarChart('bar_chart', 'barchart') # var name must be the same as the second param
barstackchart = BarStackChart('bar_stack', 'barstackchart') # var name must be the same as the second param
def index(self):
self.load_charts()
response = self.tpl.substitute(title='Open Flash Charts 2 - Python Library Demo', js=self.swfobjs, body=self.divs)
return response
def load_charts(self):
self.swfobjs = ''
self.divs = ''
self.add_chart(self.linechart)
self.add_chart(self.barchart)
self.add_chart(self.barstackchart)
def add_chart(self, chart):
self.swfobjs += chart.get_js()
self.divs += chart.get_div()
# Expose methods
index.exposed = True
cherrypy.quickstart(OFC2Demo(), '/', 'cherrypy.conf')

View File

@@ -0,0 +1,167 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Author: Emanuel Fonseca
# Email: emdfonseca<at>gmail<dot>com
# Date: 25 August 2008
import cjson
class Title(dict):
def __init__(self, title, style=None):
self['text'] = title
self.set_style(style)
def set_style(self, style):
if style:
self['style'] = style
class y_legend(Title):
pass
class x_legend(Title):
pass
##########################################
# axis classes
class axis(dict):
def __init__(self, stroke=None, tick_height=None, colour=None, grid_colour=None, steps=None):
self.set_stroke(stroke)
self.set_tick_height(tick_height)
self.set_colour(colour)
self.set_grid_colour(grid_colour)
self.set_steps(steps)
def set_stroke(self, stroke):
if stroke:
self['stroke'] = stroke
def set_tick_height(self, tick_height):
if tick_height:
self['tick_height'] = tick_height
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_grid_colour(self, grid_colour):
if grid_colour:
self['grid_colour'] = grid_colour
def set_steps(self, steps):
if steps:
self['steps'] = steps
class x_axis(axis):
def __init__(self, stroke=None, tick_height=None, colour=None, grid_colour=None, labels=None, steps=None):
axis.__init__(self, stroke, tick_height, colour, grid_colour, steps)
self.set_labels(labels)
self['orientation'] = 2
def set_labels(self, labels):
if labels:
self['labels'] = labels
class y_axis(axis):
def __init__(self, stroke=None, tick_height=None, colour=None, grid_colour=None, offset=None, max=None, min=None, steps=None):
axis.__init__(self, stroke, tick_height, colour, grid_colour, steps)
self.set_offset(offset)
self.set_max(max)
self.set_min(min)
def set_offset(self, offset):
if offset:
self['offset'] = offset
def set_max(self, max):
if max:
self['max'] = max
def set_min(self, min):
if min:
self['min'] = min
##########################################
# open_flash_chart class
class tooltip(dict):
def __init__(self, shadow=None, stroke=None, colour=None, bg_colour=None, title_style=None, body_style=None):
self.set_shadow(shadow)
self.set_stroke(stroke)
self.set_colour(colour)
self.set_background(bg_colour)
self.set_title(title_style)
self.set_body(body_style)
def set_shadow(self, shadow):
if shadow:
self['shadow'] = shadow
def set_stroke(self, stroke):
if stroke:
self['stroke'] = stroke
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_background(self, background):
if background:
self['background'] = background
def set_title(self, title):
if title:
self['title'] = title
def set_body(self, body):
if body:
self['body'] = body
##########################################
# open_flash_chart class
class open_flash_chart(dict):
def __init__(self, title, style=None):
self['title'] = Title(title, style)
def set_x_legend(self, legend):
self['x_legend'] = x_legend(legend)
def set_y_legend(self, legend):
self['y_legend'] = y_legend(legend)
def set_x_axis(self, stroke=None, tick_height=None, colour=None, grid_colour=None, labels=None, steps=None):
self['x_axis'] = x_axis(stroke, tick_height, colour, grid_colour, labels, steps)
def set_y_axis(self, stroke=None, tick_height=None, colour=None, grid_colour=None, offset=None, max=None, min=None, steps=None):
self['y_axis'] = y_axis(stroke, tick_height, colour, grid_colour, offset, max, min, steps)
def set_y_axis_right(self, stroke=None, tick_height=None, colour=None, grid_colour=None, offset=None, max=None, min=None, steps=None):
self['y_axis_right'] = y_axis(stroke, tick_height, colour, grid_colour, offset, max, min, steps)
def set_bg_colour(self, colour):
self['bg_colour'] = colour
def set_tooltip(self, shadow=None, stroke=None, colour=None, bg_colour=None, title_style=None, body_style=None):
self['tooltip'] = tooltip(shadow, stroke, colour, bg_colour, title_style, body_style)
def add_element(self, element):
try:
self['elements'].append(element)
except:
self['elements'] = [element]
def encode(self):
return cjson.encode(self)
#ofc = open_flash_chart('Example JSON')
#ofc.set_y_legend('Example Y Legend')
#ofc.set_x_legend('Example X Legend')
#ofc.set_x_axis(1, 1, '#ff0000', '#00ff00', ['sun', 'mon', 'tue'])
#ofc.set_x_axis(labels=['sun', 'mon', 'tue'])
#print cjson.encode(ofc)

View File

@@ -0,0 +1,57 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Author: Emanuel Fonseca
# Email: emdfonseca<at>gmail<dot>com
# Date: 25 August 2008
class element(dict):
def __init__(self, type=None, alpha=None, colour=None, text=None, fontsize=None, values=None):
self.set_type(type)
self.set_alpha(alpha)
self.set_colour(colour)
self.set_text(text)
self.set_fontsize(fontsize)
self.set_values(values)
def set_type(self, type):
if type:
self['type'] = type
def set_alpha(self, alpha):
if alpha:
self['alpha'] = alpha
def set_colour(self, colour):
if colour:
self['colour'] = colour
def set_text(self, text):
if text:
self['text'] = text
def set_fontsize(self, fontsize):
if fontsize:
self['font-size'] = fontsize
def set_values(self, values):
if values:
self['values'] = values
class Line(element):
def __init__(self, type=None, alpha=None, colour=None, text=None, fontsize=None, values=None):
element.__init__(self, 'line', alpha, colour, text, fontsize, values)
class Bar(element):
def __init__(self, type=None, alpha=None, colour=None, text=None, fontsize=None, values=None):
element.__init__(self, 'bar', alpha, colour, text, fontsize, values)
class BarStack(element):
def __init__(self, type=None, alpha=None, colour=None, text=None, fontsize=None, values=None):
element.__init__(self, 'bar_stack', alpha, colour, text, fontsize, values)

View File

@@ -9,7 +9,7 @@ DELETE FROM ecommerce_invoices_products WHERE invoice_id IN (
DELETE FROM ecommerce_invoices WHERE origin='amazon b2b' AND register_date LIKE '2025-04-%';
*/
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/07-2025.csv';
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/08-2025.csv';
$handle = fopen($filename, 'r');
if ($handle === false) {
die('Cannot open file: ' . $filename);

View File

@@ -1,7 +1,7 @@
<?php
// https://crm.twinpol.com/?module=EcmInvoiceOuts&action=ecommerce&amazon-wz=true
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/amazon-wz-07-2025.csv';
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/amazon-wz-08-2025.csv';
$handle = fopen($filename, 'r');
if ($handle === false) {
die('Cannot open file: ' . $filename);
@@ -18,6 +18,17 @@ while (($data = fgetcsv($handle, 0, ";")) !== false) {
if (substr($p['product_code'], -1) == '.' || substr($p['product_code'], -1) == '-') {
$p['product_code'] = substr($p['product_code'], 0, -1);
}
// ehhhhh
if ($p['product_code'] == 'FR00218_1000_amz_de') {
$p['product_code'] = 'FR00218_1000_amz_de_n';
}
if ($p['product_code'] == 'FR00225_1000_amz_de') {
$p['product_code'] = 'FR00225_1000_amz_de_n';
}
if ($p['product_code'] == 'FR00229_90_amz_de') {
$p['product_code'] = 'FR00229_90_amz_de_n';
}
// end of: ehhhhh
$p['quantity'] = floatval(str_replace(' ', '', $data[3]));
$p['total'] = floatval(str_replace(' ', '', str_replace(',', '.', $data[5])));
$p['price_netto'] = round($p['total'] / $p['quantity'], 2);

View File

@@ -9,7 +9,7 @@ DELETE FROM ecommerce_invoices_products WHERE invoice_id IN (
DELETE FROM ecommerce_invoices WHERE origin='amazon vat local' AND register_date LIKE '2025-02-%';
*/
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/07-2025.csv';
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/08-2025.csv';
$handle = fopen($filename, 'r');
if ($handle === false) {
die('Cannot open file: ' . $filename);

View File

@@ -4,7 +4,7 @@ error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
ini_set('display_errors', 1);
// read csv file tab separated
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/07-2025.csv';
$filename = getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/files/08-2025.csv';
$handle = fopen($filename, 'r');
if ($handle === false) {
die('Cannot open file: ' . $filename);
@@ -31,12 +31,12 @@ fclose($handle);
//if (count($de) == 0) {
// die('No data for DE');
//}
//createInvoice('DE', $de);
//createInvoice('DE', $de,);
//if (count($cz) == 0) {
// die('No data for CZ');
//}
//createInvoice('CZ', $cz);
if (count($cz) == 0) {
die('No data for CZ');
}
createInvoice('CZ', $cz, true);
function createInvoice($type, $products, $DO_REAL_SAVE = false)
{
@@ -57,7 +57,7 @@ function createInvoice($type, $products, $DO_REAL_SAVE = false)
$invoice->parent_address_city = 'Obrowo';
$invoice->type = 'normal';
$date = '31.07.2025';
$date = '31.08.2025';
$invoice->register_date = $date;
$invoice->sell_date = $date;
$invoice->validtill_date = $date;
@@ -87,6 +87,10 @@ function createInvoice($type, $products, $DO_REAL_SAVE = false)
if ($p[10] == 'FR00148_') {
$p[10] = 'FR00148_1000_amz_de_3pcs';
}
// (08.2025)
if ($p[10] == 'F3-W9PW-O239') {
$p[10] = 'FR00148_1000_amz_de';
}
$fromDb = $db->fetchByAssoc($db->query("SELECT id, name, code, product_category_id, unit_id FROM ecmproducts WHERE code = '$p[10]' OR amazon_code = '$p[10]'"));
if ($fromDb == false) {

View File

@@ -77,10 +77,18 @@ function getInvoices($source, $date, $type)
$row['register_date'] = date('d.m.Y', strtotime($row['register_date']));
$row['sell_date'] = date('d.m.Y', strtotime($row['sell_date']));
$row['products'] = getInvoicProducts($row['id']);
$row['sum_by_products'] = getInvoiceSumByProducts($row['id']);
$invoices[] = $row;
}
return $invoices;
}
function getInvoiceSumByProducts($invoiceId) {
$db = $GLOBALS['db'];
$query = sprintf("SELECT SUM(ip.price_netto * ip.quantity) as sum FROM ecommerce_invoices_products as ip WHERE ip.invoice_id='%s'", $invoiceId);
$result = $db->query($query);
$row = $db->fetchByAssoc($result);
return $row['sum'];
}
function getInvoicProducts($invoiceId) {
$db = $GLOBALS['db'];
$query = sprintf("SELECT p.id, p.code, p.name, ip.price_netto, ip.price_brutto, ip.quantity, ip.code as ecommerce_code, ip.vat_value FROM ecommerce_invoices_products as ip INNER JOIN ecmproducts AS p ON ip.ecmproduct_id = p.id WHERE ip.invoice_id='%s'", $invoiceId);

View File

@@ -0,0 +1,322 @@
<?php
function importApiloInvoices()
{
$apilo_config = loadApiloConfiguration();
$db = $GLOBALS['db'];
$dbRes = $db->query("SELECT COUNT(id) as last_id FROM ecommerce_invoices WHERE origin = 'apilo'");
$offset = intval($db->fetchByAssoc($dbRes)['last_id']);
$invoices = loadApiloInvoices($apilo_config['token'], $offset);
if (isset($invoices->error)) {
if (refreshApiloToken($apilo_config['refresh_token'], $apilo_config['client_id'], $apilo_config['client_secret']) == true) {
$apilo_config = loadApiloConfiguration();
$invoices = loadApiloInvoices($apilo_config['access_token'], $offset);
} else {
die('Nie udało się odświeżyć tokena apilo');
}
}
brecho(count($invoices->documents));
$platforms = loadApiloPlatformsList($apilo_config['token']);
if (isset($invoices->documents) && count($invoices->documents) > 0) {
foreach ($invoices->documents as $invoice) {
addapiloInvoice($invoice, $platforms, $apilo_config['token']);
}
}
return true;
}
function loadApiloConfiguration()
{
global $db;
$dbRes = $db->query("SELECT * FROM config WHERE category='apilo'");
$config = [];
while ($row = $db->fetchByAssoc($dbRes)) {
$config[$row['name']] = $row['value'];
}
return $config;
}
function loadApiloInvoices($token, $offset)
{
$url = "https://twinpol.apilo.com/rest/api/finance/documents/";
$params = [
'type' => 1,
'limit' => 50,
'offset' => $offset
];
$url .= '?' . http_build_query($params);
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return (object)['error' => 'HTTP Error: ' . $httpCode];
}
return json_decode($response);
}
function refreshApiloToken($refreshToken, $clientId, $clientSecret)
{
$url = "https://api.apilo.com/oauth/token";
$data = [
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $clientId,
'client_secret' => $clientSecret
];
$headers = [
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return false;
}
$tokenData = json_decode($response, true);
if (isset($tokenData['access_token'])) {
// Zapisujemy nowy token w bazie
global $db;
$db->query("UPDATE config SET value='" . $tokenData['access_token'] . "' WHERE category='apilo' AND name='access_token'");
if (isset($tokenData['refresh_token'])) {
$db->query("UPDATE config SET value='" . $tokenData['refresh_token'] . "' WHERE category='apilo' AND name='refresh_token'");
}
return true;
}
return false;
}
function addApiloInvoice($invoice, $platforms, $token)
{
$db = $GLOBALS['db'];
$platformId = loadApiloOrderPlatformId($token, $invoice->orderId);
$platformDescription = 'ERROR';
foreach ($platforms as $platform) {
if ($platform->id == $platformId) {
$platformDescription = $platform->description;
break;
}
}
$orderSource = 'Apilo | '.$platformDescription;
$invoiceType = 'normal';
if (isset($invoice->type)) {
switch ($invoice->type) {
case 31:
$invoiceType = 'correcting';
break;
case 1:
default:
$invoiceType = 'normal';
break;
}
}
$customerName = '';
$customerNip = '';
$customerCity = '';
$customerPostcode = '';
$customerAddress = '';
$customerCountry = '';
$customerCountryCode = '';
if (isset($invoice->documentReceiver)) {
$customer = $invoice->documentReceiver;
$customerName = isset($customer->companyName) ? $customer->companyName : $customer->name;
if (isset($customer->companyTaxNumber)) {
$customerNip = $customer->companyTaxNumber;
}
$customerCity = isset($customer->city) ? $customer->city : '';
$customerPostcode = isset($customer->zipCode) ? $customer->zipCode : '';
$customerAddress = isset($customer->streetName) ? $customer->streetName : '';
if (isset($customer->streetNumber)) {
$customerAddress .= ' ' . $customer->streetNumber;
}
$customerCountry = isset($customer->country) ? $customer->country : '';
$customerCountryCode = isset($customer->country) ? $customer->country : '';
}
$totalNetto = isset($invoice->originalAmountTotalWithoutTax) ? floatval($invoice->originalAmountTotalWithoutTax) : 0;
$totalBrutto = isset($invoice->originalAmountTotalWithTax) ? floatval($invoice->originalAmountTotalWithTax) : 0;
$totalVat = $totalBrutto - $totalNetto;
$currency = isset($invoice->originalCurrency) ? $invoice->originalCurrency : 'PLN';
$issueDate = isset($invoice->invoicedAt) ? date("Y-m-d", strtotime(substr($invoice->invoicedAt, 0, 10))) : date("Y-m-d");
$saleDate = isset($invoice->soldAt) ? date("Y-m-d", strtotime(substr($invoice->soldAt,0,10))) : $issueDate;
$correctedInvoiceId = ''; //isset($invoice->original_invoice_id) ? $invoice->original_invoice_id : '';
$db->query("SET NAMES utf8mb4");
$query = sprintf(
"INSERT INTO ecommerce_invoices VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%f', '%f', '%s', '%s', null, null, null, null);",
$db->quote($invoice->id),
$db->quote($invoice->documentNumber),
$invoiceType,
$issueDate,
$saleDate,
$orderSource,
isset($invoice->orderId) ? $invoice->orderId : '',
$db->quote($customerName),
$customerNip,
$db->quote($customerCity),
$customerPostcode,
$db->quote($customerAddress),
$db->quote($customerCountry),
$customerCountryCode,
$currency,
$totalNetto,
$totalBrutto,
$totalVat,
'',
$correctedInvoiceId
);
$db->query($query);
if ($db->last_error) {
error_log("Błąd dodawania faktury apilo: " . $db->last_error);
return;
}
if (isset($invoice->documentItems) && is_array($invoice->documentItems)) {
$db->query(sprintf("DELETE FROM ecommerce_invoices_products WHERE invoice_id='%s'", $db->quote($invoice->id)));
foreach ($invoice->documentItems as $item) {
addApiloInvoiceProduct($invoice->id, $item);
}
}
}
function addApiloInvoiceProduct($invoiceId, $item)
{
$db = $GLOBALS['db'];
$productId = '';
if (isset($item->sku) && !empty($item->sku)) {
$productResult = $db->query(sprintf("SELECT id FROM ecmproducts WHERE code = '%s'", $db->quote($item->sku)));
$productRow = $db->fetchByAssoc($productResult);
if ($productRow) {
$productId = $productRow['id'];
}
} else { // shipping
$productId = '165f364e-9301-25ac-5906-58e38f1de4ca';
}
$uuid = sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
$quantity = isset($item->quantity) ? intval($item->quantity) : 1;
$priceNetto = isset($item->originalPriceWithoutTax) ? floatval($item->originalPriceWithoutTax) : 0;
$priceBrutto = isset($item->originalPriceWithTax) ? floatval($item->originalPriceWithTax) : 0;
$priceVat = $priceBrutto - $priceNetto;
$taxRate = isset($item->tax) ? floatval($item->tax) : 0;
$sku = isset($item->sku) ? $item->sku : $item->name;;
$query = sprintf(
"INSERT INTO ecommerce_invoices_products VALUES('%s', '%s', '%s', '%s', '%d', '%f', '%f', '%f', '%f', '%s')",
$uuid,
$productId,
$db->quote($invoiceId),
isset($item->id) ? $db->quote($item->id) : '',
$quantity,
$priceNetto,
$priceBrutto,
$priceVat,
$taxRate,
$db->quote($sku)
);
$db->query($query);
if ($db->last_error) {
error_log("Błąd dodawania pozycji faktury apilo: " . $db->last_error);
}
}
function loadApiloPlatformsList($token) {
$url = "https://twinpol.apilo.com/rest/api/orders/platform/map/";
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return (object)['error' => 'HTTP Error: ' . $httpCode];
}
return json_decode($response);
}
function loadApiloOrderPlatformId($token, $orderId) {
$url = "https://twinpol.apilo.com/rest/api/orders/".$orderId."/";
$headers = [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Accept: application/json'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode !== 200) {
return (object)['error' => 'HTTP Error: ' . $httpCode];
}
return json_decode($response)->platformAccountId;
}
function brecho($msg)
{
echo '<br><pre>';
var_dump($msg);
echo PHP_EOL;
echo '</pre><br>';
}

View File

@@ -16,7 +16,9 @@ if (isset($_REQUEST['import_baselinker'])) {
} else if (isset($_REQUEST['wnt'])) {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/wntReader.php');
} else if (isset($_REQUEST['amazon-wz'])) {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/amazonWZ.php');
include_once(getcwd() . '/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/amazonWDT/amazonWZ.php');
} else if (isset($_REQUEST['import_apilo'])) {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/importApiloInvoices.php');
} else {
include_once(getcwd().'/modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/ecommerceInvoicesListView.php');
}

View File

@@ -68,6 +68,16 @@ $job_strings = array(
2 => 'importBaselinkerCorrectingInvoices'
);
function importApiloInvoices() {
try {
$GLOBALS['db']->query("USE preDb_0dcc87940d3655fa574b253df04ca1c3;");
require_once('modules/EcmInvoiceOuts/BimIT-eCommerceInvoices/importApiloInvoices.php');
importApiloInvoices();
return true;
} catch (Exception $e) {
return false;
}
}
function importBaselinkerInvoices()
{
try {