Implement overhead allocation for different account types, add it to binaries
This commit is contained in:
@@ -8,6 +8,6 @@
|
||||
#ifndef coster_bridge_h
|
||||
#define coster_bridge_h
|
||||
|
||||
#import "libcoster_rs.h"
|
||||
#import "coster.h"
|
||||
|
||||
#endif /* coster_bridge_h */
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *move_money_from_text(const char *rules, const char *lines, bool use_numeric_accounts);
|
||||
|
||||
void move_money_from_text_free(char *s);
|
||||
@@ -7,6 +7,9 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
5A1986F72996436500FA0471 /* OverheadAllocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A1986F62996436500FA0471 /* OverheadAllocation.swift */; };
|
||||
5A1986F92996436D00FA0471 /* MoveMoney.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A1986F82996436D00FA0471 /* MoveMoney.swift */; };
|
||||
5A1986FB2996502C00FA0471 /* FileButtonSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A1986FA2996502C00FA0471 /* FileButtonSelector.swift */; };
|
||||
5A450751298CE6D500E3D402 /* CsvDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A450750298CE6D500E3D402 /* CsvDocument.swift */; };
|
||||
5A45075B298D01EF00E3D402 /* libcoster_rs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A45075A298D01EF00E3D402 /* libcoster_rs.a */; };
|
||||
5ADD9F2D298A713300F998F5 /* FastCosterApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ADD9F2C298A713300F998F5 /* FastCosterApp.swift */; };
|
||||
@@ -36,12 +39,15 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
5A1986F62996436500FA0471 /* OverheadAllocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverheadAllocation.swift; sourceTree = "<group>"; };
|
||||
5A1986F82996436D00FA0471 /* MoveMoney.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveMoney.swift; sourceTree = "<group>"; };
|
||||
5A1986FA2996502C00FA0471 /* FileButtonSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileButtonSelector.swift; sourceTree = "<group>"; };
|
||||
5A1986FD29965BED00FA0471 /* coster.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = coster.h; path = ../../coster.h; sourceTree = "<group>"; };
|
||||
5A450750298CE6D500E3D402 /* CsvDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CsvDocument.swift; sourceTree = "<group>"; };
|
||||
5A450754298CFFAB00E3D402 /* coster-bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "coster-bridge.h"; sourceTree = "<group>"; };
|
||||
5A450755298CFFE400E3D402 /* create-lib.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "create-lib.sh"; sourceTree = "<group>"; };
|
||||
5A450756298D00AE00E3D402 /* remove-lib.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "remove-lib.sh"; sourceTree = "<group>"; };
|
||||
5A45075A298D01EF00E3D402 /* libcoster_rs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcoster_rs.a; path = "../costerrs/target/aarch64-apple-ios/release/libcoster_rs.a"; sourceTree = "<group>"; };
|
||||
5ACE47E6298D087B00834311 /* libcoster_rs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libcoster_rs.h; sourceTree = "<group>"; };
|
||||
5ADD9F29298A713300F998F5 /* FastCoster.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FastCoster.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
5ADD9F2C298A713300F998F5 /* FastCosterApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FastCosterApp.swift; sourceTree = "<group>"; };
|
||||
5ADD9F2E298A713300F998F5 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
@@ -85,7 +91,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5A450754298CFFAB00E3D402 /* coster-bridge.h */,
|
||||
5ACE47E6298D087B00834311 /* libcoster_rs.h */,
|
||||
5A1986FD29965BED00FA0471 /* coster.h */,
|
||||
5A450755298CFFE400E3D402 /* create-lib.sh */,
|
||||
5A450756298D00AE00E3D402 /* remove-lib.sh */,
|
||||
);
|
||||
@@ -131,6 +137,9 @@
|
||||
5ADD9F32298A713400F998F5 /* FastCoster.entitlements */,
|
||||
5ADD9F33298A713400F998F5 /* Preview Content */,
|
||||
5A450750298CE6D500E3D402 /* CsvDocument.swift */,
|
||||
5A1986F62996436500FA0471 /* OverheadAllocation.swift */,
|
||||
5A1986F82996436D00FA0471 /* MoveMoney.swift */,
|
||||
5A1986FA2996502C00FA0471 /* FileButtonSelector.swift */,
|
||||
);
|
||||
path = FastCoster;
|
||||
sourceTree = "<group>";
|
||||
@@ -310,7 +319,7 @@
|
||||
5A450758298D014E00E3D402 /* Remove Rust Lib */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
buildActionMask = 8;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
@@ -322,7 +331,7 @@
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "source ${PROJECT_DIR}/CosterRs/remove-lib.sh\n";
|
||||
showEnvVarsInLog = 0;
|
||||
@@ -334,9 +343,12 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5A1986FB2996502C00FA0471 /* FileButtonSelector.swift in Sources */,
|
||||
5ADD9F2F298A713300F998F5 /* ContentView.swift in Sources */,
|
||||
5A1986F92996436D00FA0471 /* MoveMoney.swift in Sources */,
|
||||
5ADD9F2D298A713300F998F5 /* FastCosterApp.swift in Sources */,
|
||||
5A450751298CE6D500E3D402 /* CsvDocument.swift in Sources */,
|
||||
5A1986F72996436500FA0471 /* OverheadAllocation.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -7,90 +7,37 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
enum ProcessType: String, Hashable {
|
||||
case MoveMoney = "Move Money"
|
||||
case OverheadAllocation = "Overhead Allocation"
|
||||
|
||||
static let values = [MoveMoney, OverheadAllocation]
|
||||
}
|
||||
|
||||
struct ContentView: View {
|
||||
@State private var showRulesPicker = false
|
||||
@State private var showLinesPicker = false
|
||||
@State private var showExportPicker = false
|
||||
@State private var document: CsvDocument?
|
||||
@State private var lines: String?
|
||||
@State private var rules: String?
|
||||
|
||||
@State var selectedProcess: ProcessType?
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Text ("Fast Coster").font(.largeTitle)
|
||||
Spacer()
|
||||
Button {
|
||||
showRulesPicker.toggle()
|
||||
} label: {
|
||||
Text("Select Rules File")
|
||||
}.fileImporter(isPresented: $showRulesPicker, allowedContentTypes: [.commaSeparatedText]) { result in
|
||||
NavigationSplitView {
|
||||
List(ProcessType.values, id: \.self, selection: $selectedProcess) { process in
|
||||
NavigationLink(process.rawValue, value: process)
|
||||
}
|
||||
} detail: {
|
||||
if let process = selectedProcess {
|
||||
switch process {
|
||||
case .MoveMoney:
|
||||
MoveMoney()
|
||||
|
||||
switch result {
|
||||
case .success(let fileUrl):
|
||||
rules = readIntoString(selectedFile: fileUrl)
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
case .OverheadAllocation:
|
||||
OverheadAllocation()
|
||||
}
|
||||
}.padding()
|
||||
Button {
|
||||
showLinesPicker.toggle()
|
||||
} label: {
|
||||
Text("Select Lines File")
|
||||
}.fileImporter(isPresented: $showLinesPicker, allowedContentTypes: [.commaSeparatedText]) { result in
|
||||
switch result {
|
||||
case .success(let fileUrl):
|
||||
lines = readIntoString(selectedFile: fileUrl)
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
}
|
||||
}.padding()
|
||||
Button {
|
||||
move_money()
|
||||
} label: {
|
||||
Text("Move money")
|
||||
}.padding()
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
.fileExporter(isPresented: $showExportPicker, document: document, contentType: .commaSeparatedText) { result in
|
||||
|
||||
if case .success = result {
|
||||
|
||||
}else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func move_money() {
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
// Run move money
|
||||
let result = move_money_from_text(rules, lines, true)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
document = CsvDocument(data: String(cString: result!))
|
||||
move_money_from_text_free(result)
|
||||
showExportPicker = true;
|
||||
} else {
|
||||
MoveMoney()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readIntoString(selectedFile: URL) -> String {
|
||||
// https://stackoverflow.com/questions/64118577/getting-the-file-xxx-couldnt-be-opened-because-you-dont-have-permission-to-v
|
||||
do {
|
||||
if selectedFile.startAccessingSecurityScopedResource() {
|
||||
let fileContent = try String(contentsOf: selectedFile)
|
||||
defer { selectedFile.stopAccessingSecurityScopedResource() }
|
||||
return fileContent
|
||||
}
|
||||
}catch let error {
|
||||
// TODO: Do something about this
|
||||
print(error)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
|
||||
53
FastCoster/FastCoster/FileButtonSelector.swift
Normal file
53
FastCoster/FastCoster/FileButtonSelector.swift
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// FileButtonSelector.swift
|
||||
// FastCoster
|
||||
//
|
||||
// Created by Michael Pivato on 10/2/2023.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct FileButtonSelector: View {
|
||||
@State private var showPicker = false
|
||||
var label: String
|
||||
var onSelected: (String) -> ()
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
showPicker.toggle()
|
||||
} label: {
|
||||
Text(label)
|
||||
}.fileImporter(isPresented: $showPicker, allowedContentTypes: [.commaSeparatedText]) { result in
|
||||
|
||||
switch result {
|
||||
case .success(let fileUrl):
|
||||
onSelected(readIntoString(selectedFile: fileUrl))
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
|
||||
func readIntoString(selectedFile: URL) -> String {
|
||||
// https://stackoverflow.com/questions/64118577/getting-the-file-xxx-couldnt-be-opened-because-you-dont-have-permission-to-v
|
||||
do {
|
||||
if selectedFile.startAccessingSecurityScopedResource() {
|
||||
let fileContent = try String(contentsOf: selectedFile)
|
||||
defer { selectedFile.stopAccessingSecurityScopedResource() }
|
||||
return fileContent
|
||||
}
|
||||
}catch let error {
|
||||
// TODO: Do something about this
|
||||
print(error)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
struct FileButtonSelector_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
FileButtonSelector(label: "Select File"){ response in
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
61
FastCoster/FastCoster/MoveMoney.swift
Normal file
61
FastCoster/FastCoster/MoveMoney.swift
Normal file
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// MoveMoney.swift
|
||||
// FastCoster
|
||||
//
|
||||
// Created by Michael Pivato on 10/2/2023.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct MoveMoney: View {
|
||||
|
||||
@State private var showExportPicker = false
|
||||
@State private var document: CsvDocument?
|
||||
@State private var lines: String?
|
||||
@State private var rules: String?
|
||||
var body: some View {
|
||||
VStack {
|
||||
FileButtonSelector(label: "Select Rules File") { result in
|
||||
rules = result
|
||||
}
|
||||
FileButtonSelector(label: "Select Lines File") { result in
|
||||
lines = result
|
||||
}
|
||||
Button {
|
||||
move_money()
|
||||
} label: {
|
||||
Text("Move money")
|
||||
}.padding()
|
||||
.fileExporter(isPresented: $showExportPicker, document: document, contentType: .commaSeparatedText) { result in
|
||||
|
||||
if case .success = result {
|
||||
|
||||
}else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
|
||||
}
|
||||
|
||||
func move_money() {
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
// Run move money
|
||||
let result = move_money_from_text(rules, lines, true)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
document = CsvDocument(data: String(cString: result!))
|
||||
move_money_from_text_free(result)
|
||||
showExportPicker = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MoveMoney_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
MoveMoney()
|
||||
}
|
||||
}
|
||||
73
FastCoster/FastCoster/OverheadAllocation.swift
Normal file
73
FastCoster/FastCoster/OverheadAllocation.swift
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// OverheadAllocation.swift
|
||||
// FastCoster
|
||||
//
|
||||
// Created by Michael Pivato on 10/2/2023.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct OverheadAllocation: View {
|
||||
@State private var lines: String?
|
||||
@State private var accounts: String?
|
||||
@State private var areas: String?
|
||||
@State private var allocationStatistics: String?
|
||||
@State private var costCentres: String?
|
||||
@State private var showExportPicker = false
|
||||
@State private var document: CsvDocument?
|
||||
@State private var accountType = "E"
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
FileButtonSelector(label: "Select Lines File") {result in
|
||||
lines = result
|
||||
}
|
||||
FileButtonSelector(label: "Select Accounts File") {result in
|
||||
accounts = result
|
||||
}
|
||||
FileButtonSelector(label: "Select Areas File") {result in
|
||||
areas = result
|
||||
}
|
||||
FileButtonSelector(label: "Select Allocation Statistics File") {result in
|
||||
allocationStatistics = result
|
||||
}
|
||||
FileButtonSelector(label: "Select Cost Centres File") {result in
|
||||
costCentres = result
|
||||
}
|
||||
TextField("Account Type", text: $accountType)
|
||||
Button {
|
||||
allocate_overheads()
|
||||
} label: {
|
||||
Text("Allocate Overheads")
|
||||
}.padding()
|
||||
.fileExporter(isPresented: $showExportPicker, document: document, contentType: .commaSeparatedText) { result in
|
||||
|
||||
if case .success = result {
|
||||
|
||||
}else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func allocate_overheads() {
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
// Run move money
|
||||
let result = allocate_overheads_from_text(lines, accounts, allocationStatistics, areas, costCentres, accountType);
|
||||
|
||||
DispatchQueue.main.async {
|
||||
document = CsvDocument(data: String(cString: result!))
|
||||
allocate_overheads_from_text_free(result)
|
||||
showExportPicker = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct OverheadAllocation_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
OverheadAllocation()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user