Importa y exporta txt de pólizas

This commit is contained in:
Mauricio Baeza 2021-07-15 21:44:29 -05:00
parent 575e80682c
commit ad74edd769
21 changed files with 323 additions and 113 deletions

View File

@ -1,2 +1,6 @@
v 0.1.0 [07-jul-2021] # Lista de cambios
- Initial version
v 0.1.0 [15-jul-2021]
- Versión inicial
- Importa txt de pólizas
- Genera txt de pólizas

View File

@ -1,3 +1,25 @@
# zaz-polizas # zaz-compaqi
Importa y exporta polizas en TXT para el sistema contable Conpaq Importa y exporta diversos archivos TXT para el sistema contable Compaqi
## Software libre, no software "gratis"
En orden de preferencia
Mauricio Baeza
```
Euros
IBAN: BE60 9671 0556 5870
SWIFT / BIC: TRWIBEB1XXX
```
* BCH: `qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d`
* FairCoin: `fJ7emvtyGfvcMuxk1nHSnS7gmeScdcZXL5`
* Monero: `43H43TpQKYdYcw2ZCnn2nbjDh3imNQg8RGYS4oP4p7Z8aeBHg6VpeaFfBoMzDTUUDdQBiGkiQUSydJB96m6MqiEuEeyoopQ`
* ETH: `0x61a4f614a30ff686445751ed8328b82b77ecfc69`
* XRP: `rLSn6Z3T8uCxbcd1oxwfGQN1Fdn5CyGujK` Tag: `6643162`
* LTC: `MBcgQ3LQJA4W2wsXknTdm2fxRSysLaBJHS`
* BTC: `3FhiXcXmAesmQzrNEngjHFnvaJRhU1AGWV`

29
conf.py
View File

@ -26,14 +26,14 @@ import logging
TYPE_EXTENSION = 1 TYPE_EXTENSION = 1
# ~ Your great extension name, not used spaces # ~ Your great extension name, not used spaces
NAME = 'ZAZPolizas' NAME = 'ZAZCompaqi'
# ~ https://semver.org/ # ~ https://semver.org/
VERSION = '0.1.0' VERSION = '0.1.0'
# ~ Should be unique, used URL inverse # ~ Should be unique, used URL inverse
ID = 'net.elmau.zaz.polizas' ID = 'net.elmau.zaz.compaqi'
# ~ If you extension will be multilanguage set: True # ~ If you extension will be multilanguage set: True
# ~ This feature used gettext, set pythonpath and easymacro in True # ~ This feature used gettext, set pythonpath and easymacro in True
@ -48,9 +48,10 @@ PATH_MSGMERGE = 'msgmerge'
# ~ Show in extension manager # ~ Show in extension manager
URL_GIT = 'https://git.cuates.net/elmau/zaz-compaqi'
PUBLISHER = { PUBLISHER = {
'en': {'text': 'El Mau', 'link': 'https://gitlab.com/mauriciobaeza'}, 'en': {'text': 'El Mau', 'link': URL_GIT},
'es': {'text': 'El Mau', 'link': 'https://gitlab.com/mauriciobaeza'}, 'es': {'text': 'El Mau', 'link': URL_GIT},
} }
# ~ Name in this folder for copy # ~ Name in this folder for copy
@ -79,13 +80,13 @@ LICENSE_ES = LICENSE_EN
INFO = { INFO = {
'en': { 'en': {
'display_name': 'ZAZ Polizas', 'display_name': 'ZAZ Compaqi',
'description': 'Process polizas from txt', 'description': 'Import and export txt files from Compaqi',
'license': LICENSE_EN, 'license': LICENSE_EN,
}, },
'es': { 'es': {
'display_name': 'ZAZ Polizas', 'display_name': 'ZAZ Compaqi',
'description': 'Procesa pólizas desde un archivo txt', 'description': 'Importa y exporta archivos txt para Compaqi',
'license': LICENSE_ES, 'license': LICENSE_ES,
}, },
} }
@ -104,21 +105,21 @@ INFO = {
# ~ For example: Shift+Ctrl+Alt+T -> T_SHIFT_MOD1_MOD2 # ~ For example: Shift+Ctrl+Alt+T -> T_SHIFT_MOD1_MOD2
PARENT = 'OfficeMenuBar' PARENT = 'OfficeMenuBar'
MENU_MAIN = { MENU_MAIN = {
'en': 'Polizas', 'en': 'Compaqi',
'es': 'Polizas', 'es': 'Compaqi',
} }
MENUS = ( MENUS = (
{ {
'title': {'en': 'Process...', 'es': 'Procesar...'}, 'title': {'en': 'Import TXT Polizas', 'es': 'Importar TXT de Pólizas'},
'argument': 'procesar', 'argument': 'import_polizas',
'context': 'calc', 'context': 'calc',
'icon': 'icon', 'icon': 'icon',
'toolbar': False, 'toolbar': False,
'shortcut': 'P_SHIFT_MOD1_MOD2', 'shortcut': 'P_SHIFT_MOD1_MOD2',
}, },
{ {
'title': {'en': 'Generate TXT...', 'es': 'Generar TXT...'}, 'title': {'en': 'Generate TXT Polizas...', 'es': 'Generar TXT de Pólizas...'},
'argument': 'generar', 'argument': 'export_polizas',
'context': 'calc', 'context': 'calc',
'icon': 'icon', 'icon': 'icon',
'toolbar': False, 'toolbar': False,

View File

@ -83,7 +83,6 @@ from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA
from com.sun.star.util import Time, Date, DateTime from com.sun.star.util import Time, Date, DateTime
from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK
from com.sun.star.text.TextContentAnchorType import AS_CHARACTER
from com.sun.star.lang import Locale from com.sun.star.lang import Locale
from com.sun.star.lang import XEventListener from com.sun.star.lang import XEventListener
@ -165,13 +164,23 @@ OBJ_RANGE = 'ScCellRangeObj'
OBJ_RANGES = 'ScCellRangesObj' OBJ_RANGES = 'ScCellRangesObj'
TYPE_RANGES = (OBJ_CELL, OBJ_RANGE) TYPE_RANGES = (OBJ_CELL, OBJ_RANGE)
OBJ_SHAPES = 'com.sun.star.drawing.SvxShapeCollection'
OBJ_SHAPE = 'com.sun.star.comp.sc.ScShapeObj' OBJ_SHAPE = 'com.sun.star.comp.sc.ScShapeObj'
OBJ_SHAPES = 'com.sun.star.drawing.SvxShapeCollection'
OBJ_GRAPHIC = 'SwXTextGraphicObject' OBJ_GRAPHIC = 'SwXTextGraphicObject'
OBJ_TEXTS = 'SwXTextRanges' OBJ_TEXTS = 'SwXTextRanges'
OBJ_TEXT = 'SwXTextRange' OBJ_TEXT = 'SwXTextRange'
CLSID = {
'FORMULA': '078B7ABA-54FC-457F-8551-6147e776a997',
}
SERVICES = {
'TEXT_EMBEDDED': 'com.sun.star.text.TextEmbeddedObject',
'TEXT_TABLE': 'com.sun.star.text.TextTable',
'GRAPHIC': 'com.sun.star.text.GraphicObject',
}
# ~ from com.sun.star.sheet.FilterOperator import EMPTY, NO_EMPTY, EQUAL, NOT_EQUAL # ~ from com.sun.star.sheet.FilterOperator import EMPTY, NO_EMPTY, EQUAL, NOT_EQUAL
class FilterOperator(IntEnum): class FilterOperator(IntEnum):
@ -225,6 +234,17 @@ class CellDeleteMode():
CDM = CellDeleteMode CDM = CellDeleteMode
class FormButtonType():
from com.sun.star.form.FormButtonType import PUSH, SUBMIT, RESET, URL
FBT = FormButtonType
class TextContentAnchorType():
from com.sun.star.text.TextContentAnchorType \
import AT_PARAGRAPH, AS_CHARACTER, AT_PAGE, AT_FRAME, AT_CHARACTER
TCAT = TextContentAnchorType
OS = platform.system() OS = platform.system()
IS_WIN = OS == 'Windows' IS_WIN = OS == 'Windows'
IS_MAC = OS == 'Darwin' IS_MAC = OS == 'Darwin'
@ -710,7 +730,8 @@ def sha512(data):
def get_config(key='', prefix='conf', default={}): def get_config(key='', prefix='conf', default={}):
name_file = FILE_NAME_CONFIG.format(prefix) name_file = FILE_NAME_CONFIG.format(prefix)
values = None values = None
path = _P.join(_P.config('UserConfig'), name_file) # ~ path = _P.join(_P.config('UserConfig'), name_file)
path = _P.join(_P.user_config, name_file)
if not _P.exists(path): if not _P.exists(path):
return default return default
@ -723,7 +744,8 @@ def get_config(key='', prefix='conf', default={}):
def set_config(key, value, prefix='conf'): def set_config(key, value, prefix='conf'):
name_file = FILE_NAME_CONFIG.format(prefix) name_file = FILE_NAME_CONFIG.format(prefix)
path = _P.join(_P.config('UserConfig'), name_file) # ~ path = _P.join(_P.config('UserConfig'), name_file)
path = _P.join(_P.user_config, name_file)
values = get_config(default={}, prefix=prefix) values = get_config(default={}, prefix=prefix)
values[key] = value values[key] = value
result = _P.to_json(path, values) result = _P.to_json(path, values)
@ -1469,7 +1491,7 @@ class LOCalc(LODocument):
self._sheets.removeByName(name) self._sheets.removeByName(name)
return return
def copy(self, name, new_name='', pos=-1): def copy_sheet(self, name, new_name='', pos=-1):
if isinstance(name, LOCalcSheet): if isinstance(name, LOCalcSheet):
name = name.name name = name.name
index = pos index = pos
@ -1750,7 +1772,8 @@ class LOSheetTables(object):
return return
class LOFormControl(LOBaseObject): # ~ class LOFormControl(LOBaseObject):
class LOFormControl():
EVENTS = { EVENTS = {
'action': 'actionPerformed', 'action': 'actionPerformed',
'click': 'mousePressed', 'click': 'mousePressed',
@ -1761,21 +1784,25 @@ class LOFormControl(LOBaseObject):
} }
def __init__(self, obj, view, form): def __init__(self, obj, view, form):
super().__init__(obj) self._obj = obj
self._view = view self._view = view
self._form = form self._form = form
self._m = view.Model self._m = view.Model
self._index = -1 self._index = -1
def __setattr__(self, name, value): # ~ def __setattr__(self, name, value):
if name in ('_form', '_view', '_m', '_index'): # ~ if name in ('_form', '_view', '_m', '_index'):
self.__dict__[name] = value # ~ self.__dict__[name] = value
else: # ~ else:
super().__setattr__(name, value) # ~ super().__setattr__(name, value)
def __str__(self): def __str__(self):
return f'{self.name} ({self.type}) {[self.index]}' return f'{self.name} ({self.type}) {[self.index]}'
@property
def obj(self):
return self._obj
@property @property
def form(self): def form(self):
return self._form return self._form
@ -1812,6 +1839,30 @@ class LOFormControl(LOBaseObject):
def enabled(self, value): def enabled(self, value):
self._m.Enabled = value self._m.Enabled = value
@property
def anchor(self):
return self.obj.Anchor
@anchor.setter
def anchor(self, value):
size = None
if hasattr(value, 'obj'):
size = getattr(value, 'size', None)
value = value.obj
self.obj.Anchor = value
if not size is None:
self.size = size
try:
self.obj.ResizeWithCell = True
except:
pass
@property
def size(self):
return self.obj.Size
@size.setter
def size(self, value):
self.obj.Size = value
@property @property
def events(self): def events(self):
return self.form.getScriptEvents(self.index) return self.form.getScriptEvents(self.index)
@ -1891,6 +1942,14 @@ class LOFormControlButton(LOFormControl):
def value(self, value): def value(self, value):
self._m.Text = Label self._m.Text = Label
@property
def url(self):
return self._m.TargetURL
@url.setter
def url(self, value):
self._m.TargetURL = value
self._m.ButtonType = FormButtonType.URL
FORM_CONTROL_CLASS = { FORM_CONTROL_CLASS = {
'label': LOFormControlLabel, 'label': LOFormControlLabel,
@ -1941,7 +2000,7 @@ class LOForm(object):
name = control.Name name = control.Name
tipo = types[control.ImplementationName] tipo = types[control.ImplementationName]
view = self.doc.CurrentController.getControl(control) view = self.doc.CurrentController.getControl(control)
control = FORM_CONTROL_CLASS[tipo](control, view) control = FORM_CONTROL_CLASS[tipo](control, view, self._obj)
control.index = i control.index = i
setattr(self, name, control) setattr(self, name, control)
self._controls[name] = control self._controls[name] = control
@ -1994,8 +2053,8 @@ class LOForm(object):
def add(self, args): def add(self, args):
name = args['Name'] name = args['Name']
tipo = args.pop('Type').lower() tipo = args.pop('Type').lower()
w = args.pop('Width') w = args.pop('Width', 1000)
h = args.pop('Height') h = args.pop('Height', 200)
x = args.pop('X', 0) x = args.pop('X', 0)
y = args.pop('Y', 0) y = args.pop('Y', 0)
control = self.doc.createInstance('com.sun.star.drawing.ControlShape') control = self.doc.createInstance('com.sun.star.drawing.ControlShape')
@ -2053,7 +2112,9 @@ class LOSheetForms(object):
def names(self): def names(self):
return self.obj.ElementNames return self.obj.ElementNames
def insert(self, name): def insert(self, name=''):
if not name:
name = f'form{self.count + 1}'
form = self.doc.createInstance('com.sun.star.form.component.Form') form = self.doc.createInstance('com.sun.star.form.component.Form')
self.obj.insertByName(name, form) self.obj.insertByName(name, form)
return LOForm(form, self._dp) return LOForm(form, self._dp)
@ -2624,8 +2685,8 @@ class LOCalcRange(object):
def visible(self): def visible(self):
cursor = self.cursor cursor = self.cursor
rangos = cursor.queryVisibleCells() rangos = cursor.queryVisibleCells()
rangos = [LOCalcRange(self.sheet[r.AbsoluteName].obj) for r in rangos] rangos = LOCalcRanges(rangos)
return tuple(rangos) return rangos
@property @property
def merged_area(self): def merged_area(self):
@ -3001,6 +3062,10 @@ class LOCalcRanges(object):
self._obj = obj self._obj = obj
self._ranges = {} self._ranges = {}
self._index = 0 self._index = 0
for r in obj:
sheet = r.Spreadsheet
rango = LOCalcRange(sheet[r.AbsoluteName])
self._ranges[rango.name] = rango
def __enter__(self): def __enter__(self):
return self return self
@ -3252,6 +3317,17 @@ class LOWriterTextRange(object):
self.text.insertTextContent(cursor, data, replace) self.text.insertTextContent(cursor, data, replace)
return return
def insert_math(self, formula,
anchor_type=TextContentAnchorType.AS_CHARACTER,
cursor=None, replace=False):
math = self._doc.create_instance(SERVICES['TEXT_EMBEDDED'])
math.CLSID = CLSID['FORMULA']
math.AnchorType = anchor_type
self.insert_content(math, cursor, replace)
math.EmbeddedObject.Component.Formula = formula
return math
def new_line(self, count=1): def new_line(self, count=1):
cursor = self.cursor cursor = self.cursor
for i in range(count): for i in range(count):
@ -3259,7 +3335,7 @@ class LOWriterTextRange(object):
return self._doc.selection return self._doc.selection
def insert_table(self, data): def insert_table(self, data):
table = self._doc.create_instance('com.sun.star.text.TextTable') table = self._doc.create_instance(SERVICES['TEXT_TABLE'])
rows = len(data) rows = len(data)
cols = len(data[0]) cols = len(data[0])
table.initialize(rows, cols) table.initialize(rows, cols)
@ -3272,9 +3348,10 @@ class LOWriterTextRange(object):
def insert_image(self, path, args={}): def insert_image(self, path, args={}):
w = args.get('Width', 1000) w = args.get('Width', 1000)
h = args.get('Height', 1000) h = args.get('Height', 1000)
image = self._doc.create_instance('com.sun.star.text.GraphicObject')
image = self._doc.create_instance(SERVICES['GRAPHIC'])
image.GraphicURL = _P.to_url(path) image.GraphicURL = _P.to_url(path)
image.AnchorType = AS_CHARACTER image.AnchorType = TextContentAnchorType.AS_CHARACTER
image.Width = w image.Width = w
image.Height = h image.Height = h
self.insert_content(image) self.insert_content(image)
@ -6470,6 +6547,17 @@ class Paths(object):
path = sys.executable path = sys.executable
return path return path
@classproperty
def user_profile(self):
path = self.config('UserConfig')
path = str(Path(path).parent)
return path
@classproperty
def user_config(self):
path = self.config('UserConfig')
return path
@classmethod @classmethod
def dir_tmp(self, only_name=False): def dir_tmp(self, only_name=False):
dt = tempfile.TemporaryDirectory() dt = tempfile.TemporaryDirectory()
@ -6619,8 +6707,12 @@ class Paths(object):
return result return result
@classmethod @classmethod
def read(cls, path, encoding='utf-8'): def read(cls, path, get_lines=False, encoding='utf-8'):
data = Path(path).read_text(encoding=encoding) if get_lines:
with Path(path).open(encoding=encoding) as f:
data = f.readlines()
else:
data = Path(path).read_text(encoding=encoding)
return data return data
@classmethod @classmethod

BIN
files/Plantilla_Compaqi.ods Normal file

Binary file not shown.

BIN
files/ZAZCompaqi_v0.1.0.oxt Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -2,10 +2,10 @@
<oor:component-data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" oor:name="Addons" oor:package="org.openoffice.Office"> <oor:component-data xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oor="http://openoffice.org/2001/registry" oor:name="Addons" oor:package="org.openoffice.Office">
<node oor:name="AddonUI"> <node oor:name="AddonUI">
<node oor:name="OfficeMenuBar"> <node oor:name="OfficeMenuBar">
<node oor:name="net.elmau.zaz.polizas" oor:op="replace"> <node oor:name="net.elmau.zaz.compaqi" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string"> <prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en">Polizas</value> <value xml:lang="en">Compaqi</value>
<value xml:lang="es">Polizas</value> <value xml:lang="es">Compaqi</value>
</prop> </prop>
<prop oor:name="Target" oor:type="xs:string"> <prop oor:name="Target" oor:type="xs:string">
<value>_self</value> <value>_self</value>
@ -13,14 +13,14 @@
<node oor:name="Submenu"> <node oor:name="Submenu">
<node oor:name="m0" oor:op="replace"> <node oor:name="m0" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string"> <prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en">Process...</value> <value xml:lang="en">Import TXT Polizas</value>
<value xml:lang="es">Procesar...</value> <value xml:lang="es">Importar TXT de Pólizas</value>
</prop> </prop>
<prop oor:name="Context" oor:type="xs:string"> <prop oor:name="Context" oor:type="xs:string">
<value>com.sun.star.sheet.SpreadsheetDocument</value> <value>com.sun.star.sheet.SpreadsheetDocument</value>
</prop> </prop>
<prop oor:name="URL" oor:type="xs:string"> <prop oor:name="URL" oor:type="xs:string">
<value>service:net.elmau.zaz.polizas?procesar</value> <value>service:net.elmau.zaz.compaqi?import_polizas</value>
</prop> </prop>
<prop oor:name="Target" oor:type="xs:string"> <prop oor:name="Target" oor:type="xs:string">
<value>_self</value> <value>_self</value>
@ -31,14 +31,14 @@
</node> </node>
<node oor:name="m1" oor:op="replace"> <node oor:name="m1" oor:op="replace">
<prop oor:name="Title" oor:type="xs:string"> <prop oor:name="Title" oor:type="xs:string">
<value xml:lang="en">Generate TXT...</value> <value xml:lang="en">Generate TXT Polizas...</value>
<value xml:lang="es">Generar TXT...</value> <value xml:lang="es">Generar TXT de Pólizas...</value>
</prop> </prop>
<prop oor:name="Context" oor:type="xs:string"> <prop oor:name="Context" oor:type="xs:string">
<value>com.sun.star.sheet.SpreadsheetDocument</value> <value>com.sun.star.sheet.SpreadsheetDocument</value>
</prop> </prop>
<prop oor:name="URL" oor:type="xs:string"> <prop oor:name="URL" oor:type="xs:string">
<value>service:net.elmau.zaz.polizas?generar</value> <value>service:net.elmau.zaz.compaqi?export_polizas</value>
</prop> </prop>
<prop oor:name="Target" oor:type="xs:string"> <prop oor:name="Target" oor:type="xs:string">
<value>_self</value> <value>_self</value>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" manifest:version="1.2"> <manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" manifest:version="1.2">
<manifest:file-entry manifest:full-path="ZAZPolizas.py" manifest:media-type="application/vnd.sun.star.uno-component;type=Python"/> <manifest:file-entry manifest:full-path="ZAZCompaqi.py" manifest:media-type="application/vnd.sun.star.uno-component;type=Python"/>
<manifest:file-entry manifest:full-path="Office/Accelerators.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/> <manifest:file-entry manifest:full-path="Office/Accelerators.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
<manifest:file-entry manifest:full-path="Addons.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/> <manifest:file-entry manifest:full-path="Addons.xcu" manifest:media-type="application/vnd.sun.star.configuration-data"/>
</manifest:manifest> </manifest:manifest>

View File

@ -5,14 +5,14 @@
<node oor:name="com.sun.star.sheet.SpreadsheetDocument"> <node oor:name="com.sun.star.sheet.SpreadsheetDocument">
<node oor:name="P_SHIFT_MOD1_MOD2" oor:op="fuse"> <node oor:name="P_SHIFT_MOD1_MOD2" oor:op="fuse">
<prop oor:name="Command"> <prop oor:name="Command">
<value xml:lang="en-US">service:net.elmau.zaz.polizas?procesar</value> <value xml:lang="en-US">service:net.elmau.zaz.compaqi?import_polizas</value>
</prop> </prop>
</node> </node>
</node> </node>
<node oor:name="com.sun.star.sheet.SpreadsheetDocument"> <node oor:name="com.sun.star.sheet.SpreadsheetDocument">
<node oor:name="T_SHIFT_MOD1_MOD2" oor:op="fuse"> <node oor:name="T_SHIFT_MOD1_MOD2" oor:op="fuse">
<prop oor:name="Command"> <prop oor:name="Command">
<value xml:lang="en-US">service:net.elmau.zaz.polizas?generar</value> <value xml:lang="en-US">service:net.elmau.zaz.compaqi?export_polizas</value>
</prop> </prop>
</node> </node>
</node> </node>

View File

@ -1,13 +1,14 @@
import uno import uno
import unohelper import unohelper
from com.sun.star.task import XJobExecutor from com.sun.star.task import XJobExecutor
from main import main from zcompaqi import main
ID_EXTENSION = 'net.elmau.zaz.polizas'
ID_EXTENSION = 'net.elmau.zaz.compaqi'
SERVICE = ('com.sun.star.task.Job',) SERVICE = ('com.sun.star.task.Job',)
class ZAZPolizas(unohelper.Base, XJobExecutor): class ZAZCompaqi(unohelper.Base, XJobExecutor):
def __init__(self, ctx): def __init__(self, ctx):
self.ctx = ctx self.ctx = ctx
@ -18,4 +19,4 @@ class ZAZPolizas(unohelper.Base, XJobExecutor):
g_ImplementationHelper = unohelper.ImplementationHelper() g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation(ZAZPolizas, ID_EXTENSION, SERVICE) g_ImplementationHelper.addImplementation(ZAZCompaqi, ID_EXTENSION, SERVICE)

View File

@ -1,21 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006"> <description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006">
<identifier value="net.elmau.zaz.polizas"/> <identifier value="net.elmau.zaz.compaqi"/>
<version value="0.1.0"/> <version value="0.1.0"/>
<display-name> <display-name>
<name lang="en">ZAZ Polizas</name> <name lang="en">ZAZ Compaqi</name>
<name lang="es">ZAZ Polizas</name> <name lang="es">ZAZ Compaqi</name>
</display-name> </display-name>
<extension-description> <extension-description>
<src lang="en" xlink:href="description/desc_en.txt"/> <src lang="en" xlink:href="description/desc_en.txt"/>
<src lang="es" xlink:href="description/desc_es.txt"/> <src lang="es" xlink:href="description/desc_es.txt"/>
</extension-description> </extension-description>
<icon> <icon>
<default xlink:href="images/zazpolizas.png"/> <default xlink:href="images/zazcompaqi.png"/>
</icon> </icon>
<publisher> <publisher>
<name xlink:href="https://gitlab.com/mauriciobaeza" lang="en">El Mau</name> <name xlink:href="https://git.cuates.net/elmau/zaz-compaqi" lang="en">El Mau</name>
<name xlink:href="https://gitlab.com/mauriciobaeza" lang="es">El Mau</name> <name xlink:href="https://git.cuates.net/elmau/zaz-compaqi" lang="es">El Mau</name>
</publisher> </publisher>
<registration> <registration>
<simple-license accept-by="user" suppress-on-update="true"> <simple-license accept-by="user" suppress-on-update="true">

View File

@ -1 +1 @@
Process polizas from txt Import and export txt files from Compaqi

View File

@ -1 +1 @@
Procesa pólizas desde un archivo txt Importa y exporta archivos txt para Compaqi

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -83,7 +83,6 @@ from com.sun.star.table.CellContentType import EMPTY, VALUE, TEXT, FORMULA
from com.sun.star.util import Time, Date, DateTime from com.sun.star.util import Time, Date, DateTime
from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK
from com.sun.star.text.TextContentAnchorType import AS_CHARACTER
from com.sun.star.lang import Locale from com.sun.star.lang import Locale
from com.sun.star.lang import XEventListener from com.sun.star.lang import XEventListener
@ -165,13 +164,23 @@ OBJ_RANGE = 'ScCellRangeObj'
OBJ_RANGES = 'ScCellRangesObj' OBJ_RANGES = 'ScCellRangesObj'
TYPE_RANGES = (OBJ_CELL, OBJ_RANGE) TYPE_RANGES = (OBJ_CELL, OBJ_RANGE)
OBJ_SHAPES = 'com.sun.star.drawing.SvxShapeCollection'
OBJ_SHAPE = 'com.sun.star.comp.sc.ScShapeObj' OBJ_SHAPE = 'com.sun.star.comp.sc.ScShapeObj'
OBJ_SHAPES = 'com.sun.star.drawing.SvxShapeCollection'
OBJ_GRAPHIC = 'SwXTextGraphicObject' OBJ_GRAPHIC = 'SwXTextGraphicObject'
OBJ_TEXTS = 'SwXTextRanges' OBJ_TEXTS = 'SwXTextRanges'
OBJ_TEXT = 'SwXTextRange' OBJ_TEXT = 'SwXTextRange'
CLSID = {
'FORMULA': '078B7ABA-54FC-457F-8551-6147e776a997',
}
SERVICES = {
'TEXT_EMBEDDED': 'com.sun.star.text.TextEmbeddedObject',
'TEXT_TABLE': 'com.sun.star.text.TextTable',
'GRAPHIC': 'com.sun.star.text.GraphicObject',
}
# ~ from com.sun.star.sheet.FilterOperator import EMPTY, NO_EMPTY, EQUAL, NOT_EQUAL # ~ from com.sun.star.sheet.FilterOperator import EMPTY, NO_EMPTY, EQUAL, NOT_EQUAL
class FilterOperator(IntEnum): class FilterOperator(IntEnum):
@ -225,6 +234,17 @@ class CellDeleteMode():
CDM = CellDeleteMode CDM = CellDeleteMode
class FormButtonType():
from com.sun.star.form.FormButtonType import PUSH, SUBMIT, RESET, URL
FBT = FormButtonType
class TextContentAnchorType():
from com.sun.star.text.TextContentAnchorType \
import AT_PARAGRAPH, AS_CHARACTER, AT_PAGE, AT_FRAME, AT_CHARACTER
TCAT = TextContentAnchorType
OS = platform.system() OS = platform.system()
IS_WIN = OS == 'Windows' IS_WIN = OS == 'Windows'
IS_MAC = OS == 'Darwin' IS_MAC = OS == 'Darwin'
@ -710,7 +730,8 @@ def sha512(data):
def get_config(key='', prefix='conf', default={}): def get_config(key='', prefix='conf', default={}):
name_file = FILE_NAME_CONFIG.format(prefix) name_file = FILE_NAME_CONFIG.format(prefix)
values = None values = None
path = _P.join(_P.config('UserConfig'), name_file) # ~ path = _P.join(_P.config('UserConfig'), name_file)
path = _P.join(_P.user_config, name_file)
if not _P.exists(path): if not _P.exists(path):
return default return default
@ -723,7 +744,8 @@ def get_config(key='', prefix='conf', default={}):
def set_config(key, value, prefix='conf'): def set_config(key, value, prefix='conf'):
name_file = FILE_NAME_CONFIG.format(prefix) name_file = FILE_NAME_CONFIG.format(prefix)
path = _P.join(_P.config('UserConfig'), name_file) # ~ path = _P.join(_P.config('UserConfig'), name_file)
path = _P.join(_P.user_config, name_file)
values = get_config(default={}, prefix=prefix) values = get_config(default={}, prefix=prefix)
values[key] = value values[key] = value
result = _P.to_json(path, values) result = _P.to_json(path, values)
@ -1469,7 +1491,7 @@ class LOCalc(LODocument):
self._sheets.removeByName(name) self._sheets.removeByName(name)
return return
def copy(self, name, new_name='', pos=-1): def copy_sheet(self, name, new_name='', pos=-1):
if isinstance(name, LOCalcSheet): if isinstance(name, LOCalcSheet):
name = name.name name = name.name
index = pos index = pos
@ -1750,7 +1772,8 @@ class LOSheetTables(object):
return return
class LOFormControl(LOBaseObject): # ~ class LOFormControl(LOBaseObject):
class LOFormControl():
EVENTS = { EVENTS = {
'action': 'actionPerformed', 'action': 'actionPerformed',
'click': 'mousePressed', 'click': 'mousePressed',
@ -1761,21 +1784,25 @@ class LOFormControl(LOBaseObject):
} }
def __init__(self, obj, view, form): def __init__(self, obj, view, form):
super().__init__(obj) self._obj = obj
self._view = view self._view = view
self._form = form self._form = form
self._m = view.Model self._m = view.Model
self._index = -1 self._index = -1
def __setattr__(self, name, value): # ~ def __setattr__(self, name, value):
if name in ('_form', '_view', '_m', '_index'): # ~ if name in ('_form', '_view', '_m', '_index'):
self.__dict__[name] = value # ~ self.__dict__[name] = value
else: # ~ else:
super().__setattr__(name, value) # ~ super().__setattr__(name, value)
def __str__(self): def __str__(self):
return f'{self.name} ({self.type}) {[self.index]}' return f'{self.name} ({self.type}) {[self.index]}'
@property
def obj(self):
return self._obj
@property @property
def form(self): def form(self):
return self._form return self._form
@ -1812,6 +1839,30 @@ class LOFormControl(LOBaseObject):
def enabled(self, value): def enabled(self, value):
self._m.Enabled = value self._m.Enabled = value
@property
def anchor(self):
return self.obj.Anchor
@anchor.setter
def anchor(self, value):
size = None
if hasattr(value, 'obj'):
size = getattr(value, 'size', None)
value = value.obj
self.obj.Anchor = value
if not size is None:
self.size = size
try:
self.obj.ResizeWithCell = True
except:
pass
@property
def size(self):
return self.obj.Size
@size.setter
def size(self, value):
self.obj.Size = value
@property @property
def events(self): def events(self):
return self.form.getScriptEvents(self.index) return self.form.getScriptEvents(self.index)
@ -1891,6 +1942,14 @@ class LOFormControlButton(LOFormControl):
def value(self, value): def value(self, value):
self._m.Text = Label self._m.Text = Label
@property
def url(self):
return self._m.TargetURL
@url.setter
def url(self, value):
self._m.TargetURL = value
self._m.ButtonType = FormButtonType.URL
FORM_CONTROL_CLASS = { FORM_CONTROL_CLASS = {
'label': LOFormControlLabel, 'label': LOFormControlLabel,
@ -1941,7 +2000,7 @@ class LOForm(object):
name = control.Name name = control.Name
tipo = types[control.ImplementationName] tipo = types[control.ImplementationName]
view = self.doc.CurrentController.getControl(control) view = self.doc.CurrentController.getControl(control)
control = FORM_CONTROL_CLASS[tipo](control, view) control = FORM_CONTROL_CLASS[tipo](control, view, self._obj)
control.index = i control.index = i
setattr(self, name, control) setattr(self, name, control)
self._controls[name] = control self._controls[name] = control
@ -1994,8 +2053,8 @@ class LOForm(object):
def add(self, args): def add(self, args):
name = args['Name'] name = args['Name']
tipo = args.pop('Type').lower() tipo = args.pop('Type').lower()
w = args.pop('Width') w = args.pop('Width', 1000)
h = args.pop('Height') h = args.pop('Height', 200)
x = args.pop('X', 0) x = args.pop('X', 0)
y = args.pop('Y', 0) y = args.pop('Y', 0)
control = self.doc.createInstance('com.sun.star.drawing.ControlShape') control = self.doc.createInstance('com.sun.star.drawing.ControlShape')
@ -2053,7 +2112,9 @@ class LOSheetForms(object):
def names(self): def names(self):
return self.obj.ElementNames return self.obj.ElementNames
def insert(self, name): def insert(self, name=''):
if not name:
name = f'form{self.count + 1}'
form = self.doc.createInstance('com.sun.star.form.component.Form') form = self.doc.createInstance('com.sun.star.form.component.Form')
self.obj.insertByName(name, form) self.obj.insertByName(name, form)
return LOForm(form, self._dp) return LOForm(form, self._dp)
@ -2624,8 +2685,8 @@ class LOCalcRange(object):
def visible(self): def visible(self):
cursor = self.cursor cursor = self.cursor
rangos = cursor.queryVisibleCells() rangos = cursor.queryVisibleCells()
rangos = [LOCalcRange(self.sheet[r.AbsoluteName].obj) for r in rangos] rangos = LOCalcRanges(rangos)
return tuple(rangos) return rangos
@property @property
def merged_area(self): def merged_area(self):
@ -3001,6 +3062,10 @@ class LOCalcRanges(object):
self._obj = obj self._obj = obj
self._ranges = {} self._ranges = {}
self._index = 0 self._index = 0
for r in obj:
sheet = r.Spreadsheet
rango = LOCalcRange(sheet[r.AbsoluteName])
self._ranges[rango.name] = rango
def __enter__(self): def __enter__(self):
return self return self
@ -3252,6 +3317,17 @@ class LOWriterTextRange(object):
self.text.insertTextContent(cursor, data, replace) self.text.insertTextContent(cursor, data, replace)
return return
def insert_math(self, formula,
anchor_type=TextContentAnchorType.AS_CHARACTER,
cursor=None, replace=False):
math = self._doc.create_instance(SERVICES['TEXT_EMBEDDED'])
math.CLSID = CLSID['FORMULA']
math.AnchorType = anchor_type
self.insert_content(math, cursor, replace)
math.EmbeddedObject.Component.Formula = formula
return math
def new_line(self, count=1): def new_line(self, count=1):
cursor = self.cursor cursor = self.cursor
for i in range(count): for i in range(count):
@ -3259,7 +3335,7 @@ class LOWriterTextRange(object):
return self._doc.selection return self._doc.selection
def insert_table(self, data): def insert_table(self, data):
table = self._doc.create_instance('com.sun.star.text.TextTable') table = self._doc.create_instance(SERVICES['TEXT_TABLE'])
rows = len(data) rows = len(data)
cols = len(data[0]) cols = len(data[0])
table.initialize(rows, cols) table.initialize(rows, cols)
@ -3272,9 +3348,10 @@ class LOWriterTextRange(object):
def insert_image(self, path, args={}): def insert_image(self, path, args={}):
w = args.get('Width', 1000) w = args.get('Width', 1000)
h = args.get('Height', 1000) h = args.get('Height', 1000)
image = self._doc.create_instance('com.sun.star.text.GraphicObject')
image = self._doc.create_instance(SERVICES['GRAPHIC'])
image.GraphicURL = _P.to_url(path) image.GraphicURL = _P.to_url(path)
image.AnchorType = AS_CHARACTER image.AnchorType = TextContentAnchorType.AS_CHARACTER
image.Width = w image.Width = w
image.Height = h image.Height = h
self.insert_content(image) self.insert_content(image)
@ -6470,6 +6547,17 @@ class Paths(object):
path = sys.executable path = sys.executable
return path return path
@classproperty
def user_profile(self):
path = self.config('UserConfig')
path = str(Path(path).parent)
return path
@classproperty
def user_config(self):
path = self.config('UserConfig')
return path
@classmethod @classmethod
def dir_tmp(self, only_name=False): def dir_tmp(self, only_name=False):
dt = tempfile.TemporaryDirectory() dt = tempfile.TemporaryDirectory()
@ -6619,8 +6707,12 @@ class Paths(object):
return result return result
@classmethod @classmethod
def read(cls, path, encoding='utf-8'): def read(cls, path, get_lines=False, encoding='utf-8'):
data = Path(path).read_text(encoding=encoding) if get_lines:
with Path(path).open(encoding=encoding) as f:
data = f.readlines()
else:
data = Path(path).read_text(encoding=encoding)
return data return data
@classmethod @classmethod

View File

@ -14,11 +14,12 @@ FILE_TARGET = 'polizas.txt'
def main(args): def main(args):
if args == 'procesar': if args == 'import_polizas':
_procesar() _import_polizas()
return
if args == 'generar': if args == 'export_polizas':
_generar() _export_polizas()
return return
@ -78,7 +79,7 @@ def _get_mov(row):
return line, uuid return line, uuid
def _generar(): def _export_polizas():
doc = app.active doc = app.active
if not 'POLIZA' in doc: if not 'POLIZA' in doc:
@ -134,8 +135,8 @@ def _generar():
return return
@app.catch_exception
def _procesar(): def _import_polizas():
if not _validate_sheets(): if not _validate_sheets():
return return
@ -149,16 +150,19 @@ def _procesar():
doc = app.active doc = app.active
sheet_catalogo = doc['Catalogo'] sheet_catalogo = doc['Catalogo']
source = doc['TXT']
target = doc['POLIZA'] target = doc['POLIZA']
data = sheet_catalogo['A1'].current_region.data data = sheet_catalogo['A1'].current_region.data
catalog = {str(int(r[1])): r[2] for r in data} catalog = {str(int(r[1])): r[2] for r in data}
path_txt = app.paths.get_file(filters='txt')
try:
data = app.paths.read(path_txt, True)
except UnicodeDecodeError:
data = app.paths.read(path_txt, True, 'ISO-8859-1')
rows = [] rows = []
data = source['A1'].current_region.data for r in data:
for row in data:
r = row[0]
header = r[:2].strip() header = r[:2].strip()
if header == IS_HEADER: if header == IS_HEADER:
date = app.dates.str_to_date(r[3:11].strip(), '%Y%m%d', True) date = app.dates.str_to_date(r[3:11].strip(), '%Y%m%d', True)
@ -202,12 +206,6 @@ def _validate_sheets():
app.errorbox(message) app.errorbox(message)
return False return False
if not 'TXT' in doc:
message = 'No se encontró la hoja: TXT'
app.error(message)
app.errorbox(message)
return False
if not 'POLIZA' in doc: if not 'POLIZA' in doc:
message = 'No se encontró la hoja: POLIZA' message = 'No se encontró la hoja: POLIZA'
app.error(message) app.error(message)

View File

@ -1,14 +1,14 @@
This file is part of ZAZPolizas. This file is part of ZAZCompaqi.
ZAZPolizas is free software: you can redistribute it and/or modify ZAZCompaqi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ZAZPolizas is distributed in the hope that it will be useful, ZAZCompaqi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with ZAZPolizas. If not, see <https://www.gnu.org/licenses/>. along with ZAZCompaqi. If not, see <https://www.gnu.org/licenses/>.

View File

@ -1,14 +1,14 @@
This file is part of ZAZPolizas. This file is part of ZAZCompaqi.
ZAZPolizas is free software: you can redistribute it and/or modify ZAZCompaqi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ZAZPolizas is distributed in the hope that it will be useful, ZAZCompaqi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with ZAZPolizas. If not, see <https://www.gnu.org/licenses/>. along with ZAZCompaqi. If not, see <https://www.gnu.org/licenses/>.