This commit is contained in:
Dennis Eichhorn 2023-09-10 18:58:34 +00:00
parent 015dbe23d9
commit 246db89f3c
14 changed files with 170 additions and 24 deletions

View File

@ -43,22 +43,22 @@ $pdf->setSubject($this->data['bill_subtitle'] ?? '');
$pdf->setKeywords(\implode(', ', $this->data['keywords'] ?? []));
$pdf->language = $bill->language;
$pdf->attributes['legal_name'] = $this->data['legal_company_name'] ?? 'Jingga e.K.';
$pdf->attributes['legal_name'] = $this->data['legal_company_name'] ?? 'Jingga e. K.';
$pdf->attributes['address'] = $this->data['bill_company_address'] ?? 'Gartenstr. 26';
$pdf->attributes['city'] = $this->data['bill_company_city'] ?? '61206 Woellstadt';
$pdf->attributes['city'] = $this->data['bill_company_city'] ?? '61206 Wöllstadt';
$pdf->attributes['ceo'] = $this->data['bill_company_ceo'] ?? 'Dennis Eichhorn';
$pdf->attributes['tax_office'] = $this->data['bill_company_tax_office'] ?? 'HRB ???';
$pdf->attributes['tax_number'] = $this->data['bill_company_tax_id'] ?? '123456789';
$pdf->attributes['tax_office'] = $this->data['bill_company_tax_office'] ?? 'HRA 5058';
$pdf->attributes['tax_number'] = $this->data['bill_company_tax_id'] ?? '16 814 6253 3';
$pdf->attributes['terms'] = $this->data['bill_company_terms'] ?? 'https://jingga.app/terms';
$pdf->attributes['bank_name'] = $this->data['bill_company_bank_name'] ?? 'Volksbank Mittelhessen';
$pdf->attributes['swift'] = $this->data['bill_company_swift'] ?? '.....';
$pdf->attributes['bank_account'] = $this->data['bill_company_bank_account'] ?? '.....';
$pdf->attributes['swift'] = $this->data['bill_company_swift'] ?? 'VBMHDE5F';
$pdf->attributes['bank_account'] = $this->data['bill_company_bank_account'] ?? 'DE62 5139 0000 0084 8044 10';
$pdf->attributes['website'] = $this->data['bill_company_website'] ?? 'www.jingga.app';
$pdf->attributes['email'] = $this->data['bill_company_email'] ?? 'info@jingga.app';
$pdf->attributes['phone'] = $this->data['bill_company_phone'] ?? '+49 0152 ????';
$pdf->attributes['phone'] = $this->data['bill_company_phone'] ?? '+49 152 04337728';
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
@ -290,6 +290,10 @@ $pdf->setFont('helvetica', 'B', 8);
$pdf->Write(0, $lang[$pdf->language]['Currency'] . ': ' . $bill->currency, '', 0, 'L', false, 0, false, false, 0);
$pdf->Ln();
$pdf->setFont('helvetica', 'B', 8);
$pdf->Write(0, $lang[$pdf->language]['TaxRemark'], '', 0, 'L', false, 0, false, false, 0);
$pdf->Ln();
$pdf->setFont('helvetica', '', 8);
$pdf->Write(0, $bill->termsText, '', 0, 'L', false, 0, false, false, 0);
$pdf->Ln();

View File

@ -33,6 +33,7 @@ return [
'Taxes' => 'Taxes',
'Terms' => 'Terms',
'PaymentTerms' => 'Payment Terms',
'TaxRemark' => 'No sales tax will be charged in accordance with §19 (1) UStG.',
],
'de' => [
'InvoiceNo' => 'Belegnummer',
@ -52,5 +53,6 @@ return [
'Taxes' => 'USt',
'Terms' => 'AGB',
'PaymentTerms' => 'Zahlungsbedingungen',
'TaxRemark' => 'Es wird gemäß §19 Abs. 1 UStG keine Umsatzsteuer berechnet.',
],
];

View File

@ -9,13 +9,13 @@
"l11n": {
"en": {
"subject": "Billing",
"body": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Billing</title></head><body style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.5;\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr><td><table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"600\" style=\"margin: 0 auto; background-color: #ffffff;\"><tr><td style=\"padding: 40px 0; text-align: center;\"><h1 style=\"margin-top: 0; color: #000000; font-size: 24px;\">Billing</h1><p style=\"margin-bottom: 20px;\">Dear {user_name},</p><p style=\"margin-bottom: 20px;\">Thank you for for doing business with us.</p><p style=\"margin-bottom: 20px;\">Attached kindly find your bill.</p><p style=\"margin-top: 40px;\">Jingga e.K. - www.jingga.app - CEO Dennis Eichhorn</p></td></tr></table></td></tr></table></body></html>",
"bodyalt": "Dear {user_name},\n\nThank you for doing business with us.\n\nAttached kindly find your bill.\n\n\nJingga e.K. - www.jingga.app - CEO Dennis Eichhorn"
"body": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Billing</title></head><body style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.5;\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr><td><table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"600\" style=\"margin: 0 auto; background-color: #ffffff;\"><tr><td style=\"padding: 40px 0; text-align: center;\"><h1 style=\"margin-top: 0; color: #000000; font-size: 24px;\">Billing</h1><p style=\"margin-bottom: 20px;\">Dear {user_name},</p><p style=\"margin-bottom: 20px;\">Thank you for for doing business with us.</p><p style=\"margin-bottom: 20px;\">Attached kindly find your bill.</p><p style=\"margin-top: 40px;\">Jingga e.K. - www.jingga.app - CEO Dennis Eichhorn - Amtsgericht Friedberg HRA 5058</p></td></tr></table></td></tr></table></body></html>",
"bodyalt": "Dear {user_name},\n\nThank you for doing business with us.\n\nAttached kindly find your bill.\n\n\nJingga e.K. - www.jingga.app - CEO Dennis Eichhorn - Amtsgericht Friedberg HRA 5058"
},
"de": {
"subject": "Rechnungsstellung",
"body": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Abrechnung</title></head><body style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.5;\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr><td><table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"600\" style=\"margin: 0 auto; background-color: #ffffff;\"><tr><td style=\"padding: 40px 0; text-align: center;\"><h1 style=\"margin-top: 0; color: #000000; font-size: 24px;\">Abrechnung</h1><p style=\"margin-bottom: 20px;\">Sehr geehrte/r {user_name},</p><p style=\"margin-bottom: 20px;\">Vielen Dank für Ihre Geschäftsbeziehung mit uns.</p><p style=\"margin-bottom: 20px;\">Im Anhang finden Sie Ihre Rechnung.</p><p style=\"margin-top: 40px;\">Jingga e.K. - www.jingga.app - CEO Dennis Eichhorn</p></td></tr></table></td></tr></table></body></html>",
"bodyalt": "Sehr geehrte/r {user_name},\n\nvielen Dank für Ihre Geschäftsbeziehung mit uns.\n\nIm Anhang finden Sie freundlicherweise Ihre Rechnung.\n\n\nJingga e.K. - www.jingga.app - CEO Dennis Eichhorn"
"body": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Abrechnung</title></head><body style=\"font-family: Arial, sans-serif; font-size: 16px; line-height: 1.5;\"><table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\"><tr><td><table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"600\" style=\"margin: 0 auto; background-color: #ffffff;\"><tr><td style=\"padding: 40px 0; text-align: center;\"><h1 style=\"margin-top: 0; color: #000000; font-size: 24px;\">Abrechnung</h1><p style=\"margin-bottom: 20px;\">Sehr geehrte/r {user_name},</p><p style=\"margin-bottom: 20px;\">Vielen Dank für Ihre Geschäftsbeziehung mit uns.</p><p style=\"margin-bottom: 20px;\">Im Anhang finden Sie Ihre Rechnung.</p><p style=\"margin-top: 40px;\">Jingga e.K. - www.jingga.app - CEO Dennis Eichhorn - Amtsgericht Friedberg HRA 5058</p></td></tr></table></td></tr></table></body></html>",
"bodyalt": "Sehr geehrte/r {user_name},\n\nvielen Dank für Ihre Geschäftsbeziehung mit uns.\n\nIm Anhang finden Sie freundlicherweise Ihre Rechnung.\n\n\nJingga e.K. - www.jingga.app - CEO Dennis Eichhorn - Amtsgericht Friedberg HRA 5058"
}
},
"send": false

View File

@ -312,6 +312,12 @@
"type": "TINYINT(1)",
"null": false
},
"billing_type_transfer_sign": {
"description": "1 = from->to direction, -1 = to->from direction = credit note",
"name": "billing_type_transfer_sign",
"type": "TINYINT(1)",
"null": false
},
"billing_type_account_format": {
"name": "billing_type_account_format",
"type": "VARCHAR(255)",

View File

@ -327,7 +327,7 @@ final class ApiAttributeController extends Controller
return;
}
/** @var \Modules\Billing\Models\BillAttributeTypeL11n $billAttributeTypeL11n */
/** @var BaseStringL11n $billAttributeTypeL11n */
$billAttributeTypeL11n = BillAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $billAttributeTypeL11n, BillAttributeTypeL11nMapper::class, 'bill_attribute_type_l11n', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $billAttributeTypeL11n);
@ -387,7 +387,7 @@ final class ApiAttributeController extends Controller
return;
}
/** @var \Modules\Billing\Models\BillAttributeType $billAttributeType */
/** @var AttributeType $billAttributeType */
$billAttributeType = BillAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $billAttributeType, BillAttributeTypeMapper::class, 'bill_attribute_type', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $billAttributeType);
@ -418,7 +418,7 @@ final class ApiAttributeController extends Controller
/** @var AttributeValue $old */
$old = BillAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute();
/** @var \Modules\Attribute\Models\Attribute $type */
/** @var \Modules\Attribute\Models\Attribute $attr */
$attr = BillAttributeMapper::get()
->with('type')
->where('id', $request->getDataInt('attribute') ?? 0)
@ -514,7 +514,7 @@ final class ApiAttributeController extends Controller
return;
}
/** @var \Modules\Billing\Models\BillAttributeValueL11n $billAttributeValueL11n */
/** @var BaseStringL11n $billAttributeValueL11n */
$billAttributeValueL11n = BillAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $billAttributeValueL11n, BillAttributeValueL11nMapper::class, 'bill_attribute_value_l11n', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $billAttributeValueL11n);

View File

@ -38,6 +38,7 @@ use Modules\Messages\Models\EmailMapper;
use Modules\SupplierManagement\Models\NullSupplier;
use Modules\SupplierManagement\Models\Supplier;
use Modules\SupplierManagement\Models\SupplierMapper;
use phpOMS\Application\ApplicationAbstract;
use phpOMS\Autoloader;
use phpOMS\Localization\ISO4217CharEnum;
use phpOMS\Localization\ISO639x1Enum;
@ -60,6 +61,22 @@ use phpOMS\Views\View;
*/
final class ApiBillController extends Controller
{
/**
* Constructor.
*
* @param null|ApplicationAbstract $app Application instance
*
* @since 1.0.0
*/
public function __construct(ApplicationAbstract $app = null)
{
parent::__construct($app);
if ($this->app->moduleManager->isActive('WarehouseManagement')) {
$this->app->eventManager->importFromFile(__DIR__ . '/../../WarehouseManagement/Admin/Hooks/Manual.php');
}
}
/**
* Api method to update a bill
*

View File

@ -397,7 +397,7 @@ final class ApiBillTypeController extends Controller
return;
}
/** @var \Modules\Billing\Models\BillTypeL11n $billTypeL11n */
/** @var BaseStringL11n $billTypeL11n */
$billTypeL11n = BillTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $billTypeL11n, BillTypeL11nMapper::class, 'bill_type_l11n', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $billTypeL11n);

View File

@ -355,7 +355,10 @@ final class ApiPriceController extends Controller
*/
public function updatePriceFromRequest(RequestAbstract $request, Price $new) : Price
{
$new->name = $new->name !== 'base' && $request->hasData('name') ? $request->getDataString('name') : $new->name;
$new->name = $new->name !== 'base'
? ($request->getDataString('name') ?? $new->name)
: $new->name;
$new->promocode = $request->getDataString('promocode') ?? $new->promocode;
$new->item = $request->hasData('item') ? new NullItem((int) $request->getData('item')) : $new->item;

View File

@ -280,14 +280,16 @@ final class ApiTaxController extends Controller
return;
}
/** @var array $combinations */
$combinations = \json_decode(\file_get_contents($path), true);
foreach ($combinations as $combination) {
/** @var TaxCombination[] $old */
$old = TaxCombinationMapper::getAll()
->with('clientCode')
->with('itemCode')
->where('clientCode/valueStr', $combination['account_code'])
->where('itemCode/valueStr', $combination['item_code'])
->where('clientCode/valueStr', $combination['account_code'] ?? '')
->where('itemCode/valueStr', $combination['item_code'] ?? '')
->execute();
if (\count($old) !== 1) {
@ -297,7 +299,7 @@ final class ApiTaxController extends Controller
$old = \reset($old);
$new = clone $old;
$new->taxCode = $combination['tax_code'];
$new->taxCode = $combination['tax_code'] ?? '';
$this->updateModel($request->header->account, $old, $new, TaxCombinationMapper::class, 'tax_combination', $request->getOrigin());
}
@ -390,7 +392,7 @@ final class ApiTaxController extends Controller
return;
}
/** @var \Modules\Billing\Models\TaxCombination $taxCombination */
/** @var \Modules\Billing\Models\Tax\TaxCombination $taxCombination */
$taxCombination = TaxCombinationMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $taxCombination, TaxCombinationMapper::class, 'tax_combination', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $taxCombination);

View File

@ -404,10 +404,12 @@ final class CliController extends Controller
private function parseDate(string $date, Supplier $supplier, array $formats) : ?\DateTime
{
if ((!empty($supplier->getAttribute('bill_date_format')->value->valueStr))) {
return \DateTime::createFromFormat(
$dt = \DateTime::createFromFormat(
$supplier->getAttribute('bill_date_format')->value->valueStr ?? '',
$date
) ?? new \DateTime('1970-01-01');
);
return $dt === false ? new \DateTime('1970-01-01') : $dt;
}
foreach ($formats as $format) {

View File

@ -424,7 +424,7 @@ class Bill implements \JsonSerializable
* @var BillElement[]
* @since 1.0.0
*/
private array $elements = [];
public array $elements = [];
/**
* Reference to other Bill (delivery note/credit note etc).

View File

@ -50,6 +50,8 @@ class BillType implements \JsonSerializable
public bool $transferStock = true;
public int $sign = 1;
/**
* Localization
*

View File

@ -44,6 +44,7 @@ final class BillTypeMapper extends DataMapperFactory
'billing_type_transfer_type' => ['name' => 'billing_type_transfer_type', 'type' => 'int', 'internal' => 'transferType'],
'billing_type_default_template' => ['name' => 'billing_type_default_template', 'type' => 'int', 'internal' => 'defaultTemplate'],
'billing_type_transfer_stock' => ['name' => 'billing_type_transfer_stock', 'type' => 'bool', 'internal' => 'transferStock'],
'billing_type_sign' => ['name' => 'billing_type_sign', 'type' => 'bool', 'internal' => 'sign'],
'billing_type_is_template' => ['name' => 'billing_type_is_template', 'type' => 'bool', 'internal' => 'isTemplate'],
];

View File

@ -0,0 +1,107 @@
{
"office_supplies": {
"en": [
"office supplies", "pencil", "pen", "notepad", "note", "highlighter",
"eraser", "paperclip", "binder clip", "staples", "stapler", "tape dispenser",
"scotch tape", "rubber bands", "marker", "whiteboard marker",
"whiteboard eraser", "desk organizer", "calendar", "desk calendar",
"file folder", "folder", "hanging file folder", "envelope", "stamp",
"scissor", "calculator", "ruler", "trash can", "recycling bin",
"cabinet labels", "paper towels", "cleaning supplies", "sticky tack",
"adhesive putty", "wall calendar"
],
"de": []
},
"it_supplies": {
"en": [
"keyboard", "mouse", "mice", "USB drive", "network cable", "toner",
"printer paper", "ink", "cartridge"
],
"de": []
},
"it_equipment": {
"en": [
"PC", "computer", "laptop", "monitor", "switch", "psu", "server", "printer",
"router", "webcam", "headset", "hard drive", "microphone", "macbook", "phone",
"cellphone", "mobile phone"
],
"de": []
},
"internet_phone": {
"en": [
"domain", "website", "web server", "phone", "internet", "cellphone"
],
"de": []
},
"furniture": {
"en": [
"sofa", "armchair", "table", "chair", "bed", "nightstand", "dresser", "wardrobe",
"bookshelf", "desk", "cabinet", "couch", "recliner", "tv stand", "kitchen island",
"barstool", "bathroom vanity", "dining room hutch", "chest of drawers",
"bench", "credenza", "sideboard", "ottoman", "headboard", "footboard",
"chaise lounge", "patio furniture", "outdoor dining set", "hammock",
"bean bag", "stool", "cubby storage", "shoe rack", "coat rack", "futon",
"crib", "playpen"
],
"de": []
},
"appliances": {
"en": [
"refrigerator", "oven", "stove", "microwave", "dishwasher", "washing machine",
"clothes dryer", "freezer", "coffee maker", "toaster", "blender",
"food processor", "kettle", "rice cooker", "slow cooker",
"toaster oven", "air conditioner", "heater", "ceiling fan", "vacuum cleaner",
"iron", "hair dryer", "curling iron", "shaver",
"air purifier", "dehumidifier", "humidifier", "garbage disposal",
"trash compactor", "range hood", "juicer", "mixer", "grill",
"bread maker", "ice maker", "water dispenser", "ductless mini-split system",
"wall oven", "induction cooktop", "espresso machine", "can opener",
"portable air conditioner", "hot water dispenser", "skillet",
"popcorn maker", "margarita machine", "deep fryer", "griddle", "scale"
],
"de": []
},
"cleaning": {
"en": [
"broom", "mop", "dustpan", "bucket", "sponge", "scrub brush", "cloth",
"paper towels", "trash bags", "trash can", "vacuum cleaner",
"carpet cleaner", "glass cleaner", "cleaner", "disinfectant wipes",
"toilet brush", "toilet bowl cleaner", "bathroom cleaner", "tile cleaner",
"oven cleaner", "dishwashing liquid", "detergent", "fabric softener",
"stain remover", "trash can liners", "baking soda", "vinegar",
"dust mask", "cleaning caddy", "window squeegee", "feather duster",
"lint roller", "air freshener", "gloves", "degreaser", "floor wax",
"furniture polish", "shoe polish", "stainless steel cleaner", "rust remover",
"grill brush", "lime scale remover", "rug cleaner", "furniture stain remover"
],
"de": []
},
"marketing": {
"en": [
"flyer", "brochure", "article", "trade fair", "exhibition", "trade show",
"advertising", "social media", "market research", "marketing", "catalogue",
"catalog", "price list"
],
"de": []
},
"food": {
"en": [
"wine", "beer", "schnaps", "water", "cola", "fanta", "juice", "sprite", "coffe",
"cake", "ice cream", "pudding", "donut",
"nudle", "steak", "fish", "salat", "burger", "fries", "potato", "soup"
],
"de": []
},
"hotel": {
"en": [
"hotel", "motel", "hostel"
],
"de": []
},
"travel": {
"en": [
"flight", "taxi", "train", "uber", "parking"
],
"de": []
}
}